길/Javascript 기본

primitive type vs. reference type

7he8oy 2021. 1. 25. 15:53

지금은 확실하게 개념이 잡혀있는 것 같지 않기에 우선 오늘 알게 된 것을 정리하고 넘어가려고 한다.

 

 

primitive type은 

 

let a = 3;

과 같이 선언과 할당과정을 거칠 때,

1) a에 주소를 할당  (a의 주소는 300) 

 

2)3에 주소를 할당 (b의 주소는 500)

 

3) a가 값으로 3의 주소를 가짐 (300의 주소를 가지는 변수명 a는 주소 500을 값으로 가짐)

과 같은 방식이 이루어진다.

 

이때, 만약

a = 4;

로 a에 다른 값을 할당하면,

 

1) 4에 주소를 할당 (4의 주소는 501)

 

2) a가 값으로 4의 주소를 가짐 (300의 주소를 가지는 변수명 a는 주소 501을 값으로 가짐)

 

따라서 숫자 3은 주소 500에 그대로 남아있는 상태가 된다. (주소 500에 할당되어 있는 데이터는 불변)

 

 

복사값 변경

let b = a

를 실행하면,

a가 갖고있는 값인 4의 주소(501)을 b가 그대로 가져간다.

 

b = 20

를 실행하면 

20이 또한 새로운 주소값을 부여 받고,

20의 주소를 b가 값으로 가지게 된다.

이때, a는 4의 주소를 값으로 갖고 있으므로, 결과적으로는 a=4, b=20이 된다. 즉 b의 변경에 a가 영향을 받지 않는다.

 

Reference Type

참조 자료형도 선언과 할당 과정을 하지만, 중간에 참조 과정을 한번 더 거치는 것이다.

 

let obj = {a:1, b:'abc'}

이때,

1) obj에 주소를 할당. (주소는 400) 

2) 여러 개의 주소(ex 1000~1001)를 값으로 갖는 공간을 부여하고 이곳에 주소를 할당. 이 주소는 obj가 값으로 가진다. (주소가 400인 obj는 600을 값으로 가짐.)

 

3) 1과 'abc'에 각각을 값으로 갖는 주소를 부여 (601,602)

 

4) 주소 1000과 1001에 601과 602을 값으로 부여.

 

 

이런 과정을 거친다. 결과적으로

 

주소 400에 obj가 값으로 주소 600을 가짐. -> 주소 600은 주소 1000과 1001을 값으로 가짐. -> 각 주소 1000과 1001은 값으로 601과 602를 각각 가진다.

 

 

만약 

obj.a =2;

를 실행한다면 

603주소에 2를 할당하고,

주소 1000에 주소 603이 할당된다.

따라서 obj 내부의 a가 갖는 주소값은 바뀌지만 변수명 a에 주소 1000이 할당 되어 있다는 사실은 변하지 않는다.

따라서 

let obj2 = obj1

을 실행했을 때,

obj2는 obj1가 갖고 있던 주소(즉 1000과 1001이 담겨있는 주소인 600)을 갖게 되므로

obj2.a = 3

을 실행하게 되면 

주소 1000이 갖고있는 값인 601의 값이 3이라는 숫자가 부여받은 주소로 바뀐다.

따라서 obj와 obj1은 같은 값인 600을 값으로 갖고 , 600은 1000,1001을 값으로 갖고 있으니 

위 구문에서 1000이 갖고 있는 값을 바꿔버렸으므로

obj의 a값도 바뀌게 된다.

 

 


간단한? 버전

자바스크립트에는 heap이라는 빈공간이 있다.

 

원시타입의 경우에는 

변수와 값을 짝짓는다.

 

그러나 reference type은 heap안에서의 위치를 변수와 짝짓는다.

따라서, 

let array = [a,b]

를 선언했다면, array라는 변수는 heap에서의 특정 address값을 갖는다. (ex. address 1)

그리고 heap에 address 1은 a,b를 값으로 갖는다. 

 

따라서 

primitive type의 경우 값을 그대로 복사하지만 

reference type의 경우는 '주소(address 1)'를 복사하기 때문에 복사한 데이터에서 값을 변경하면 기존 데이터에 영향이 가게된다.

' > Javascript 기본' 카테고리의 다른 글

왜 typeof null은 object일까.  (0) 2021.01.26
mutator method인지 참고하는 사이트  (0) 2021.01.25
Array.isArray('object')  (0) 2021.01.25
for...in... vs for..of  (0) 2021.01.25
arr.push / arr.pop()  (0) 2021.01.25