[JavaScript]  값과 레퍼런스
Front-End/JavaScript

[JavaScript] 값과 레퍼런스

 

 

JavaScript의 타입👀

 

JavaScript의 데이터 타입은 크게 두가지로 나눌 수 있다. 원시 타입(Primitive data type)객체 타입(Object / reference type)이다.

 

 

원시 타입은 다음과 같다.

 

Number(숫자)
String(문자열)
boolean(논리형)
undefined
null
Symbol(ES6부터 제공)

 

 

객체 타입은 다음을 포함한다.

function(함수)
Array(배열)
Object(객체)

 

 

JavaScript에서 원시 타입을 제외한 모든 값은 '객체' 이다. 즉, 함수나 배열 모두 객체로 본다.
원시타입과 객체 타입의 차이점은 값의 저장 형태이다.

 

 

 

 

 

 

원시 타입

 

흔히 원시 타입은 불변성(immutable)을 갖는다고 말한다.
원시 타입을 변수에 할당할 때값을 그대로 저장하는데, 그값은 절대로 바꿀 수 없다.

 

 

 

🤔let으로 선언하면 값 수정이 가능한거 아닌가?

 

let a = 1;
a = 2;

위의 코드와 같이 값을 재할당하면 a의 값이 2로 수정된 것처럼 보이지만
실제로는 '2'라는 값이 새로운 메모리에 생성되고, a가 2를 가리키도록 바뀌는 것이다.

 

 

 

참조 타입

 

참조타입은 값을 주소로 저장한다.

변수에 할당된 주소를 따라가면 값에 접근할 수 있는데, 이 값은 heap 형태의 별도 메모리 공간에 위치해있다.

 

 

 

깊은 복사와 얕은 복사

 

이러한 차이는 값을 복사할 때 두드러진다.

 

원시타입은 언제나 값을 복사한다. 이를 깊은 복사라고 한다.

let a = 2;
let b = a;
b++;

a; // 2
b; // 3

a에 2라는 값을 할당하고 b에 a의 값을 복사해주었다.
b에는 a 값의 다른 사본이 들어간다.

a와 b가 가리키고 있는 값은 별개이므로 b의 값을 바꾼다고 해서 a까지 동시에 값이 변경되지 않는다.

 

 


그렇다면 참조타입은 어떨까.
참조타입은 반드시 레퍼런스 사본을 생성한다. 이를 얕은 복사라고 한다.

let c = [ 1, 2, 3];
let d = c;

d.push(4);

c; // [ 1, 2, 3, 4]
d; // [ 1, 2, 3, 4]

마찬가지로 c에 배열을 넣어주고 d에 c를 복사해주었다.
원시 타입과는 다르게 d의 값을 변경하자 c의 값 또한 변경되었다.
d에 c를 복사할 때 c가 가진 레퍼런스 즉, 값의 주소를 복사했기 때문이다.

레퍼런스를 통해 c와 d는 동일한 값을 바라보기 때문에 d를 변경하면 c와 d가 동시에 바라보고있는 값 자체를 변경하게된다.

 

 

 

 

 

여기까지 왔으면 이제 이 코드를 이해할 수 있다.

 

function foo(x){

    x.push(4);
       x; // [ 1, 2, 3, 4]

       x = [ 4, 5, 6];

}

let a = [ 1, 2, 3];
foo(a);

a; //[ 1, 2, 3, 4]

a를 함수의 인자로 넘기면, a의 레퍼런스가 x에 복사된다.
x와 a는 레퍼런스를 통해 모두 동일한 값을 가리키므로 x를 통해 값을 추가하고
x는 새로운 레퍼런스를 가리킨다.

 

 

 

 

 

 

 

 

 

 

 

📌

You dont't know JS, 카일 심슨