0. 원시 타입 ? 객체 타입 ?
자바스크립트가 제공하는 7가지 데이터 타입(숫자, 문자열, 불리언, null, undefined, 심벌, 객체 타입)은 크게 원시 타입과 객체 타입으로 구분할 수 있습니다.
차이점
- 원시 값은 변경 불가능한 값. 객체는 변경 가능한 값입니다
- 원시 값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장됩니다. 그러나, 객체를 변수에 할당하면 변수에는
참조 값
이 저장됩니다. - 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달됩니다. 이를
값에 의한 전달
이라고 합니다. 이에 비해 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달됩니다. 이를참조에 의한 전달
이라 합니다.
🤔 상수(const)와 변경 불가능한 값은 뭐가 다른데?
일단 변수
와 값
을 구분할 필요가 있습니다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 / 메모리 공간을 식별하는 이름이고,
값은 변수에 저장된 데이터로서 변경 불가능한 값
입니다.
상수인 const(재할당이 금지된 변수) 또한 값을 저장하기 위한 메모리 공간을 필요로 하기 때문에 변수입니다.
상수가 그냥 변수와 다른 점은 재할당이 되지 않는다는 것입니다.
변경 불가능한 값은'값'이고, 상수는 '변수'이기 때문에 둘 다 변경이 불가능하다는 성질을 가지고 있다 할지라도 다릅니다.
1. 원시 타입
문자열과 불변성
원시 값을 저장하기 위해서는, 먼저 확보해야 하는 메모리 공간의 크기를 결정해야 합니다.
이를 위해 원시 타입 별로 메모리 공간의 크기가 미리 정해져 있습니다.
문자열은.. 어떻게 될까요? 문자열은 0개 이상의 문자로 이루어진 집합을 말합니다.
1개의 문자는 2바이트의 메모리 공간에 저장됩니다.
음..
만약 약 300쪽분량의 문자열이 있다면..? '주현'이라는 문자열과 다른 크기를 가진 메모리 공간에 저장되어야 하겠죠?
따라서 문자열은 몇 개의 문자로 이루어졌느냐에 따라 필요한 메모리 공간의 크기가 결정됩니다.
숫자값은 1도, 100000도 동일한 8바이트가 필요한데,
문자열의 경우 몇 개의 문자로 이루어졌냐를 따져봐야 합니다.
C에서는 char을 이용할 뿐 문자여 타입은 존재하지 않고,
Java에서는 문자열을 String 객체로 처리합니다.
그러나 자바스크립트는! 🎉 원시 타입은 문자열 타입을 제공합니다.
자바스크립트의 문자열은 원시 타입이며 변경할 수 없습니다. => 문자열이 생성된 이후에는 변경할 수 없습니다!
let str = 'Hello'
str = 'World'
첫 번째 문에서 Hello가 생성되고, str은 Hello가 저장된 메모리 공간의 첫 번째 메모리 셀을 가리킵니다.
두 번째 문이 실행되면 Hello를 수정하는 것이 아니라, 새로운 문자열 world를 메모리에 생성하고, str은 이 새 메모리 공간을 가리킵니다.
🤔 으음.. str.length는 뭔가요?
사실... 문자열은 유사 배열 객체였습니다 짜잔!
유사 배열 객체란, 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체를 말합니다.
문자열은 배열처럼 인덱스를 통해 각 문자에 접근할 수도 있고, for문을 순회할 수도 있으며, legnth 프로퍼티를 갖습니다.
분명 원시 타입인 문자열이 무슨 일일까요..?!
이건 원시 값을 객체처럼 사용하면 원시 값을 감싸는 래퍼 객체로 자동 변환되는 '래퍼 객체'에 대해서 알아봐야 하겠네요(나중에..!)
하지만 중요한 것은 str[0] = 'P'
처럼 생성된 문자열의 일부 문자를 변경하려고 하면 반영되지 않는다는 것입니다.
문자열은 변경 불가능한 값이기 때문이죠!
값에 의한 전달
변수에 변수를 할당하면 무엇이 어떻게 전달될까요?
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 살당되는 변수의 원시 값이 복사되어 전달됩니다.
이를 '값에 의한 전달'이라고 합니다.
let score = 80
let copy = score
console.log(score, copy) // 80, 80
console.log(score === copy) // true
둘 다 같은 80이라는 값을 가집니다.
하지만, score 변수와 copy 변수의 값 80은 다른 메모리 공간에 저장된 별개의 값입니다.
따라서 score 변수를 변경하더라도 copy 변수의 값에는 어떠한 영향도 주지 못합니다.
🤔 오케 값이 전달
사실 엄격하게 표현하자면 변수에는 값이 전달되는게 아니라 메모리 주소가 전달됩니다.
변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하기 때문에. 자신이 기억하는 메모리 주소를 전달하고(copy에 score 메모리 주소 전달)
copy는 score이 기억하고 있는 메모리 주소를 통해 저장된 값에 접근해서 80을 참조합니다.
2. 객체 타입(변경 가능한 값)
방금까지 변경 불가능한 원시 값을 보고 왔습니다
원시 값을 할당한 변수는 원시 값 자체를 값으로 갖고, 변수가 값에 접근하는 식별자 역할을 했습니다.
그러나 객체 타입은, 객체를 할당한 변수가 가진 메모리 주소로 접근하게 되면 값
이 아닌 참조 값
에 접근하게 됩니다.참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체입니다.
원시 타입 할당 변수 -> 진짜 값
객체 타입 할당 변수 -> 참조 값
-> 진짜 값
이 되는 것입니다.
원시 값은 변경이 불가능하므로 값을 변경하려면 재할당 외에는 방법이 없지만,
객체는 재할당 없이 객체를 직접 변경할 수 있습니다. 프로퍼티를 동적으로 추가, 생신, 삭제할 수도 있습니다.
참조에 의한 전달
let person ={
name : 'Lee'
}
let copy = person;
객체를 가리키는 변수(person)을 다른 변수(copy)에 할당하면,
원본의 값이 아닌 참조 값
이 복사되어 전달됩니다.
이를 참조에 의한 전달이라고 합니다.
이 말은, person, copy 두 개의 식별자가 하나의 객체를 공유하게 된다는 말입니다.
원본, 사본 어느 한 쪽에서 객체를 변경하면 서로 영향을 주고받게 됩니다.
'✍ 공부 > JavaScript' 카테고리의 다른 글
[ 모던 자바스크립트 Deep Dive ] 프로퍼티와 식별자 네이밍 규칙 (0) | 2023.01.11 |
---|---|
[ 모던 자바스크립트 Deep Dive ] 옵셔널 체이닝 연산자 && null 병합 연산자 (1) | 2022.12.30 |
[ 모던 자바스크립트 Deep Dive ] 반복문 (0) | 2022.12.30 |
[ 모던 자바스크립트 Deep Dive ] 타입 변환 (자바스크립트 ! 두번) (0) | 2022.12.26 |
[ 모던 자바스크립트 Deep Dive ] 반복문 + 레이블문 (0) | 2022.12.26 |