데이터의 타입에는 크게 두가지가 있다.
일반적으로 기본형은 할당이나 연산시 복제되고, 참조형은 참조된다고 알려져있다. 그치만 엄밀히 말하면 둘 다 복제를 한다.
- 변수 : 변할 수 있는 무언가 = 데이터
- 식별자 : 어떤 데이터를 식별하는데 사용하는 이름, 즉 변수명!
변수는 변경 가능한 데이터가 담길 수 있는 공간이라고 이해하는게 정확하다.
let a ;
위와같은 명령을 받은 컴퓨터는 메모리에서 비어있는 공간 하나를 확보한다. 그리고 그 공간의 이름을 a라고 지정한다.
let a;
a = 'abc';
이제 a에 데이터를 할당하면 데이터를 저장하기 위한 별도의 메모리 공간을 다시 확보해 'abc'를 저장하고, 그 주소를 변수 영역에 저장하는 식으로 동작합니다.
데이터의 성질에 따라 변수영역 / 데이터 영역으로 구분한다.
let a = 'abc';
a = 'abcdef'
위 처럼 a에 다른 값을 재할당했을때는 기존 데이터 영역에 저장된 'abc'의 값이 변경되는게 아니라 다른 메모리 공간에 'abcdef'를 저장하고 그 주솟값을 참조한다.
불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 메모리이다.
기본형 데이터인 number, string, boolean, null, undefined, symbol은 모두 불변값이다.
let a = 5;
let b = 5;
a = 7;
💡 불변값의 성질은 한번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다는 것이다.
참조형 데이터와 기본형 데이터와의 차이는 객체 변수 영역이 별도로 존재한다는 점이다.
let a = 10;
let b = a;
b=20
console.log(a===b) // false
console.log(b) // 20
기본형에서 데이터를 복사하고 변경하면 a와 b는 서로 다른 주소를 바라보게 되어 일치하지 않는다고 나온다.
let obj ={
c : 15
}
let obj2 = obj
obj2.c = 20
console.log(obj === obj2) // true
console.log(obj.c) // 20
참조형 데이터를 복사하고 obj2.c의 값을 변경하면 obj.c의 값도 변경된다.
이 코드에서 obj와 obj2는 같은 객체를 가리키고 있다.
let obj2 = obj
라인에서, obj의 참조값이 obj2에 복사된다. 그러므로 obj와 obj2는 같은 객체를 가리키게 된다. 즉, obj와 obj2는 메모리 상에서 동일한 위치를 참조하고 있다.
따라서 obj2.c = 20을 통해 obj2의 c 속성을 변경하면, obj도 동일한 객체를 가리키고 있기 때문에 obj.c의 값도 변경된다. obj와 obj2는 서로 다른 변수이지만, 객체 자체는 같기 때문에 한 변수를 통해 객체를 수정하면 다른 변수에서도 수정된 결과를 볼 수 있다.
얕은 복사는 바로 아래 단계의 값만 복사하는 방법이고, 깊은 복사는 내부의 모든 값들을 찾아 전부 복사하는 방법이다.
중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다는 의미이다.
사본을 바꾸면 원본도 바뀌고, 원본을 바꾸면 사본도 바뀌게 된다.
👉 참조형 데이터를 불변값으로 사용하고 싶다면 내부 프로퍼티들을 일일이 복사하면 된다!(=깊은복사)