객체를 제외한 모든 타입은 원시 값(불변 값)으로 값을 그대로 할당합니다.
아래와 같이 newName
에 name
을 할당하고 다시 "jennie"
로 값을 재할당 한 후 name
과 newName
을 확인해 보면 데이터의 불변성(newName의 값을 재할당 해도 name의 값이 변하지 않음)을 확인할 수 있습니다.
let name = "sara";
let newName = name;
newName = "jennie";
console.log(name, newName); // sara, jennie
이렇게 값이 변하지 않는 것 이 당연해 보이지만 그 이유는 아래와 같습니다.
1. 메모리(1002
)에 식별자 name
을 저장합니다.
... | 1002 | ... |
---|---|---|
이름: name 값: |
2. "sara"
를 비어있는 다른 메모리(5003
) 공간에 저장합니다.
... | 1002 | ... |
---|---|---|
이름: name 값: |
... | 5003 | .. |
---|---|---|
"sara" |
3. name
과 newName
은 같은 string 타입의 "sara"
를 저장한 메모리(5003
) 주소를 참조하게 됩니다.
... | 1002 | 1003 |
---|---|---|
이름: name 값: @5003 | 이름: newName 값: @5003 |
... | 5003 | .. |
---|---|---|
"sara" |
4. newName
에 "jennie"
를 재할당 하면 string 타입의 "jennie"
를 메모리(5004
)에 저장하고 newName
은 해당 주소(5004
)를 참조합니다.
... | 1002 | 1003 |
---|---|---|
이름: name 값: @5003 | 이름: newName 값: @5004 |
... | 5003 | 5004 |
---|---|---|
"sara" | "jennie" |
이와 같이 원시형에서는 데이터를 변경할 때 가리키는 주소를 직접 바꿔놓게 되기 때문에 불변성을 유지할 수 있습니다.
객체 타입의 데이터로 값이 저장된 주소 값을 참조합니다.
같은 주소 값을 참조한다는 것은 얕은 복사(shallow copy)를 확인하면 이해할 수 있습니다.
아래와 같이 obj2.b 값을 재할당했을 때 obj.b의 값도 변경된 경우를 얕은 복사라고 합니다.
const obj = {
a: 1,
b: 2,
};
const obj2 = obj;
obj2.b = 3;
console.log(obj, obj2); // {a: 1, b: 3}, {a: 1, b: 3}
이렇게 obj의 값이 같이 변경된 이유는 아래와 같습니다.
1. obj
를 메모리(1002
)에 선언합니다.
... | 1002 | 1003 |
---|---|---|
이름: obj 값: @5002 | 이름: obj2 값: @1002 |
2. 메모리 구조 공간 하나에는 값이 하나씩밖에 못 들어가기 때문에 메모리(7103~
) 공간을 확보합니다.
5002 | 5003 | 5004 | 5005 |
---|---|---|---|
@7103~ | 1 | 2 | 3 |
확보한 공간 메모리(7103 ~
)에 프로퍼티(5003
, 5004
)를 하나씩 할당합니다.
7103 | 7104 | ... |
---|---|---|
이름: a 값: @5003 | 이름: b 값: @5004 -> @5005(3으로 재할당) |
3. obj2
에 obj
를 할당했으므로 obj
는 1002
를 참조합니다.
4. obj2.b
에 3
으로 재할당(5005
) 하는 경우 obj
와 obj2
는 같은 메모리(5002
) 주소 값을 참조합니다.
이와 같이 얕은 복사는 obj2
는 새로운 객체를 만든 것이 아니라 obj
와 같은 주소 값을 참조하므로 obj2.b
를 변경했지만 obj
도 같이 변하는 것을 확인할 수 있습니다.
참고 - 코어 자바스크립트