본문 바로가기
개발

[JS] 데이터 타입(Data type) - 복사, 불변성과 가변성

by _Jun 2022. 1. 12.

이번 포스팅의 내용을 잘 이해하기 위해서는 [JS] 메모리와 데이터에 대한 이해가 필요합니다.

 

[JS] 메모리와 데이터

컴퓨터는 우리의 명령(코드)에 따라 데이터를 조작하는 동작을 수행합니다. 이때, 조작의 대상인 데이터와 컴퓨터가 수행해야하는 명령어들은 컴퓨터의 메모리(RAM)에 저장됩니다. 코드에서 명

hangeoreum.tistory.com

 


 

자바스크립트에서 데이터에는 타입이 존재하고, 기본형(Primitive type)과 참조형(Reference type)으로 구분 가능합니다. 기본형에는 숫자(Number), BigIng, 문자열(String), 불리언(Boolean), null, undefined, 심볼(Symbol)이 포함됩니다. 참조형에는 객체(Object)가 있고 배열(Array), 함수(Function), Date, 정규표현식(RegExp), Map, WeakMap, Set, WeakSet 등이 객체에 포함됩니다.

 

자바스크립트 데이터 타입

 


 

 1. 기본형과 참조형의 차이 

1-1. 복사 방식

기본형과 참조형은 복사되는 방식이 다릅니다. 기본형의 경우 값 그대로 복사되고(copy-by-value), 참조형의 경우 참조에 의해 복사됩니다(copy-by-reference). 이러한 차이점은 메모리에 값이 저장되는 방식이 기본형과 참조형에서 다르기 때문입니다.

 

기본형

let a = "value";
let b = a;

기본형의 복사 방식

기본형의 경우 '변수명과 연결된 메모리(@2)' 안에 '값이 담긴 메모리 주솟값(@1001)'을 저장합니다. 따라서 기본형을 복사하는 경우 '새로운 변수명 메모리(@3)'에는 '복사하려는 값이 담긴 메모리 주솟값(@1001)'이 저장됩니다. 

 

참조형

let obj1 = {
  a: 10,
  b: "value",
}

let obj2 = obj1;

참조형의 복사 방식

참조형의 경우 '객체의 속성값들을 저장해놓은 메모리 묶음의 주솟값(@5001 ~ ?)'을 '새로운 메모리(@1000)'에 저장하고, '변수명과 연결된 메모리(@2)'의 값에는 @1000의 주소를 저장합니다. 따라서 참조형을 복사하는 경우 '새로운 병수명 메모리(@3)에는 '객체 속성값 메모리 묶음의 주소를 값으로 갖는 메모리의 주소(@1000)'가 저장됩니다.

 

1-2. 불변성(Immutability)과 가변성(mutability)

기본형은 값을 가진 메모리 주소를 저장/복사하고, 참조형은 주솟값을 가진 메모리 주소를 저장/복사합니다. 이러한 차이에서 기본형과 참조형의 불변성이 달라지게 됩니다. 

 

기본형은 불변성을 띕니다

여기서 불변성은 변수명과 연결된 메모리가 참조하는 메모리 안에 저장된 값이 변경될 수 없다는 뜻입니다.

 

변수 a와 b가 연결된 메모리(변수 a,b와 연결된 메모리를 각각 a 메모리, b 메모리라고 부르겠습니다)의 값에는 "value"를 저장한 메모리 주솟값이 저장되어 있습니다. 이때, 변수 a의 값을 100으로 바꾸면 메모리가 어떻게 변하는지 보겠습니다.

 

let a = "value";
let b = a;

a = 100;

기본형의 불변성

 

a의 값을 변경했을 때, 원래 a 메모리가 참조하고 있던 @1001의 값("value")는 절대로 바뀌지 않습니다. 새롭게 할당하려는 값(100)을 새로운 메모리에 저장하고 a 메모리의 값을 100이 저장된 메모리 주솟값으로 설정합니다. 이처럼 기존에 생성된 값은 절대로 변하지 않기 때문에 불변성이라고 부릅니다.

 

참조형은 가변성을 띕니다

let obj = {
  a: 10,
  b: "value",
}

obj.a = 1000;

참조형의 가변성

객체의 속성을 변경했을 때, 속성값과 연결된 메모리(@5001)의 값은 변경(@1002 -> @1003)됩니다. 하지만, obj 메모리에 저장된 주솟값은 변하지 않고 @1000로 동일합니다. obj 메모리의 값은 변하지 않은 상태에서 객체의 내부 속성값을 바꿀 수 있는 것입니다.

 

기본형에서 값을 변경할 때 새로운 값을 저장한 메모리를 만들어야 했던 것과 달리, 새로운 객체를 참조하는 메모리를 만들지 않고도 객체를 변경할 수 있기 때문에 참조형은 가변성을 띈다고 하는 것입니다. 

 


이때 주의해야할 점이 하나 있습니다.

 

let obj = {
  a: 10,
  b: "value",
}

obj = {
  prop: "value",
}

 

위와 같은 코드를 실행할 경우에는 obj 메모리의 값이 변경됩니다. 새로운 객체를 할당하여 객체 자체를 바꾸는 것이기 때문에 메모리에 새로운 객체가 저장되고 그 주소값이 obj 메모리 값으로 저장됩니다.

 

객체 자체를 변경하는 경우

 

즉, 참조형이 가변성을 띈다는 것은 참조형 데이터 자체를 변경하는 경우가 아니라 그 안에 있는 속성을 변경할 때만 성립합니다.

 

 

참고) 불변성을 띄는 불변객체를 만들 수 있는 방법도 많이 존재합니다.(Object.defineProperty, Object.freeze, etc.)

 

 

 

References

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures

https://ko.javascript.info

코어 자바스크립트 - 정재남

'개발' 카테고리의 다른 글

ASCII code와 Unicode  (0) 2022.04.05
DOM이란  (0) 2022.03.01
[JS] 메모리와 데이터  (0) 2022.01.10
[JS] Event Delegation(이벤트 위임)  (0) 2022.01.06
[JS] Event Bubbling과 Capturing  (0) 2022.01.06

댓글