Javascript 원시값과 참조값 이해하기 | 불변성

고광필·2022년 2월 3일
2

Front

목록 보기
3/33

https://github.com/yjs03057/33-js-concepts
모든 자바스크립트 개발자가 알아야 하는 33가지 개념 중
2. 원시자료형
3. 값 타입과 참조 타입에 대해 공부했습니다.
추가로 불변성의 정의, 장점도 같이 적겠습니다.

왜 알아야 하는가?

자바스크립트에서 변수에 값을 할당하는 과정을 알 수 있습니다.
이를 통해 왜 {} === {}가 false인지 이해할 수 있습니다.
이번 내용을 공부해야 코드를 작성할 때 내가 생각한대로 데이터가 바뀔 수 있습니다.

불변성

'변하지 않는다'는 뜻입니다. 아래에서 추가로 설명하겠습니다.

원시값 (Primitive)

string, number, boolean, null, undefined, bigint, symbol의 타입을 원시형 자료형이라고 하고, 이런 값들을 원시값이라고 합니다.

원시값의 특징은 변수에 값이 저장되고, 불변합니다.

참조값 (객체)

참조형은 위의 원시형을 제외한 객체를 뜻합니다. Array나 Function 역시 Object기 때문에 이에 해당합니다.

참조값의 특징은 변수에 객체의 주소를 뜻하는 주소값(참조값)이 저장되고, 가변합니다.

원시값과 참조값의 특징을 변수에 값을 할당하는 과정을 통해 깊게 이해해보겠습니다.

자바스크립트 변수에 값을 할당하는 과정

let a = 3;
let b = a;
console.log(a); // 3
console.log(b); // 3
a = 5;
console.log(a); // 5
console.log(b); // 3

변수 a를 선언하면서 값으로 3을 할당하고, 변수 b를 선언해 a의 값을 할당합니다.
이후 a의 값을 5로 바꾸는 코드입니다.

원시값의 할당 과정

자바스크립트에서 메모리 영역은 변수 영역(stack)과 데이터 영역(heap)이 있습니다.
변수 영역은 변수를 모아놓은 곳이고, 데이터 영역은 실제 값들을 모아놓은 곳입니다.
변수 a1 ~ a십억에 1을 할당한고 할 때, 데이터 영역에는 값 1이 10억개 만들어지지 않고, 1개만 만들어집니다.
그리고 변수들이 그 데이터와 연결되고, 이걸 변수에 값이 들어갔다고 합니다.

원시값은 데이터 영역에 값 3을 정의하고, 변수 영역에 a를 선언해서 둘을 연결합니다.
이렇게 된 것을 '변수a는 값으로 3을 가진다'라고 할 수 있습니다.

let b = a; 부분은
변수 영역에 b를 할당하고, a에 연결된 데이터 영역의 값 3을 b에도 연결합니다.

이후 a = 5; 부분은
데이터 영역에서 a와 연결된 3을 5로 바꾸지 않고, 데이터 영역에 새로 값 5를 추가하고, a를 이와 연결합니다.

이처럼 원시값은 변수 영역이 어떤 데이터에 연결될지는 바뀔 수 있지만, 데이터 영역의 값은 바뀌지 않기 때문에 '불변하다'고 합니다.
데이터 영역에 값이 그대로 남아 있고, 같은 값을 공유해도 서로 영향을 주지 않습니다.

참조값의 할당 과정

let a = { one: 1 };
let b = a;
console.log(a); // { one: 1 }
console.log(b); // { one: 1 }

b.two = 2;
console.log(a); // { one: 1, two: 2}
console.log(b); // { one: 1, two: 2}

위 코드는 변수 a에 객체 { one: 1 }을 할당하고, 변수 b에 a의 값을 할당합니다.
이후 b.two = 2 부분에서 변수b의 객체 내부를 수정했지만, 출력 결과 a도 함께 바뀌어 버렸습니다.

참조값은 데이터 영역에 객체의 주소값을 할당하게 됩니다.
위 코드는 변수 a의 값에 { one: 1 }이라는 객체의 주소값이 들어가 객체를 가리키고 있는 상태이고,
b = a; 부분에서 변수 b에도 a의 값 (객체의 주소값)이 들어가서 변수 a, b는 같은 객체를 가리키고 있는 상태가 됩니다.

그래서 b.two = 2로 b가 가리키고 있는 객체 (a도 동일한 객체를 가리키고 있습니다)를 수정했을 때, a가 가리키고 있는 값도 바뀌게 되는것입니다.
얕은 복사 상태와 같습니다.

Const

const 키워드를 사용한 변수는 변수의 값을 재할당, 재선언 할 수 없습니다.

const a = 3;
a = 5; // Error

const b = { one: 1};
b = { two: 2}; // Error
b.one = 10; // Ok

위 코드는 const 키워드로 변수 a를 할당해 값 3을 할당하고, 이후 값을 5로 바꿉니다.
이 때 const는 변수의 값을 바꿀 수 없기 때문에 에러가 발생합니다.

그러나 변수가 객체라면, 변수의 값은 객체의 주소값이 됩니다.
b = { two: 2}; 부분은 변수b의 값을 새로운 객체의 주소값으로 바꾸는 것이기 때문에 에러가 발생합니다.
b.one = 10; 부분은 변수b는 계속 같은 객체의 주소값을 가지고 있고, 그 객체안의 one이라는 변수의 원시값이 바뀐것이기 때문에 가능합니다.

const는 변수가 가지고 있는 값이 수정 불가하기 때문에, 객체일 때 객체 안의 속성의 값이 바뀌는 것은 가능합니다.

정리

자바스크립트에서 변수에 값이 할당되는 과정을 통해서 원시값과 참조값이 각각 어떻게 할당되는지 알아보았습니다.
그로 인해 어떤 상황들이 발생하는지도 알아보았습니다.

추가로 불변성을 유지할 때 장점으로
데이터가 어떻게 바뀔지 예측이 가능하다, 메모리의 데이터 영역을 재사용하기 때문에 (위의 십억개의 1을 떠올려보세요) 메모리 성능에 좋다 등이 있습니다.

내용이 그래도 이해가 안가시는분들이 있으시다면 집으로 이해하시면 됩니다.
사람1이 ㅇㅇ구 ~ 101호에 산다고 하고, 사람2가 같은주소를 말한다면 두 사람이 같이 사는것으로 생각할 것입니다. 주소가 완전히 동일하기 때문입니다.

그리고 집이 똑같이 구조, 생김새 등이 모두 같다고 해도 한국에 지어진 집과 미국에 지어진 집은 주소가 다르니까 다른 집이 됩니다.

참고

https://www.youtube.com/watch?v=eV4Yzssr9MA
https://www.youtube.com/watch?v=N6F26EN2JpE&t=316s

profile
이해하는 개발자를 희망하는 고광필입니다.

1개의 댓글

comment-user-thumbnail
2023년 10월 13일

감사합니다 ㅎㅎ

답글 달기