[JavaScript] 원시값과 참조값

조은·2022년 9월 16일
0

1. 변수란?

  • 변수는 위치(주소)를 기억하는 저장소이다. (포인터의 개념)
  • 위치란 메모리 상의 주소(address)를 의미한다.

즉, 변수란, 메모리 주소에 접근하기 위해 사람이 이해할 수 있는 언어로 지정한 식별자이다.

변수를 선언하는 것부터가 메모리를 사용하는 것이기 때문에
-> 변수사용을 최소한으로 하여, 페이지의 성능을 유지해야한다.


javaScript는 동적 타이핑 언어로 (느슨한 타입 - loosely typed이라고 부르기도 한다.),
변수의 자료형 명세 필요없이 값이 할당되는 과정에서 자동으로 자료형이 결정 (Type Inference: 타입 추론)된다.
이에 반해 C계열의 언어나 java 등은 정적 타이핑 언어로, 변수를 선언할 때 자료형을 꼭 명시해야 한다.





2. 원시 값과 참조 값

자바스크립트의 변수 타입에는 크게

  1. Primitive type(원시타입)
  2. Reference Type(참조타입)

으로 나누어져 있다.

원시 값(Primitive type)

string, number, bigint, boolean, undefined, ES6 부터 추가된 symbol이 원시 값에 해당한다.

원시 값은 변수에 할당될 때,

1. 메모리에 선언한 값을 고정 크기로 저장하고
2. 해당 저장된 값을 변수가 직접적으로 가리키는 형태를 띤다.

또한 하나의 값에 대한 진술이 절대 변하지않는 불변성을 갖고있다.

불변성이란, 한 원시 값 변수에 대한 메모리 위치는 변하지 않는다 는 것을 의미한다.

예시를 살펴보자

let a = 1;
let b = 1;
console.log(a === b);
// 변수가 가리키는 값도 같고, 메모리 상의 위치도 같으므로 true

b = 2;
console.log(a === b);
// b는 2로 재할당되고, 2에 해당하는 새로운 메모리 주소에 할당되기 때문에 false

let c = 1;
console.log(a === c);
// 1은 기존에 저장되어 있었기 때문에 기존 메모리 주소를 할당받는다. 따라서 true 

이는 원시값에 모두 공통으로 적용된다. 아래는 문자열로 해본 결과이다.

즉, 새로운 변수에 기존에 한번 메모리에 저장된 원시값이 있다면 새로운 메모리 저장소를 생성하는 것이 아닌 그 주소를 할당 받는다.

이러한 특성이 원시값의 불변성이다.


참조 값(Object/Reference type)

자바스크립트에서 원시 타입을 제외한 나머지는 참조타입(객체 - Object)이다.
배열, 객체, 함수가 대표적이다.

참조값의 데이터 자체는

  • 별도의 메모리 공간(heap)에 저장되며,
  • 변수에 할당 시 데이터에 대한 주소 (힙(Heap) 메모리의 주소값)가 저장된다.
  • 자바스크립트 엔진은 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근한다.

원시타입과 가장 큰 차이점은 변수의 크기가 동적으로 변한다는 것이다.

다른 언어와 달리 자바스크립트는 메모리 위치에 직접 접근하는 것을 허용하지 않고, 객체의 메모리 공간을 직접 조작하는 일은 불가능하다.

객체를 조작할 때는 객체 자체가 아니라 해당 객체에 대한 참조를 조작하는 것이다. 이런 이유로 객체를 가리키는 값은 ‘참조로 접근한다’고 한다.

객체를 변수에 할당하면 실제 객체의 값은 별도의 메모리 공간에 저장되며 그 공간을 참조하는 주소를 변수는 값으로 갖는다.

즉, 참조값은 생성된 객체가 저장된 메모리 공간의 주소를 의미한다.

참조 값을 변수에서 다른 변수로 복사하면 그 값이 객체 자체가 아니라 힙에 저장된 객체를 가리키는 포인터라는 점이다.
복사 후에는 두 변수는 정확히 같은 객체를 가리킨다.
따라서 한쪽을 조작하면 다른 쪽에도 반영된다.

let x = {k: 1}
let y = {k: 1}
console.log(x,y, x===y) // {k: 1} {k: 1} false - 값은 같지만 메모리 주소(참조값)가 다름.

x.k=7
y=x
console.log(x,y, x===y) // {k: 7} {k: 7} true - y는 x의 같은 메모리 주소(참조값)을 복사하여 전달받았기 때문에 값과 메모리 주소가 같음.

x.k=2
console.log(x,y, x===y) // {k: 2} {k: 2} true - 같은 메모리 공간을 서로 참조하고 있으므로 객체의 프로퍼티가 갱신 되었을 때 공유되어 true값이 나옴

let z= y
console.log(x,y, x===y) // {k: 2} {k: 2} {k: 2} true - 같은 메모리 공간에 대한 주소를 x,y가 가지고 있으며 이 값을 z가 전달 받았으므로 모두 같은 메모리 주소를 참조하고 있음.

x.k=9
console.log(x,y, x===y) // {k: 9} {k: 9} {k: 9} true - 같은 메모리 공간을 참조하는 x,y,z에서 값을 변경하였을 때 그 영향을 다른 변수도 받게되어 모두 갱신됨.

출처

profile
끄적끄적....

0개의 댓글