Javascript Object vs Primitives (Primitives vs reference type)

먼저 조금은 이해가 가지 않는 코드에 대해 이야기해보자.

1
2
3
4
5
6
7
8
9
const me = {
  age : 21,
}
 
const you = me;
you.age = 30;
 
console.log(you);         //30
console.log(me);          //30


me 라는 객체에서 나이에  21을 할당했다.  그리고 you 에 me 의 객체를 똑같이 넣어주고 you의 나이를 30 으로 할당했다. 이때 me 의 객체와 you 의 객체는 따로 있으므로 나이는 다르다고 생각 할 수 있다. 하지만 값은 둘 다 30으로 동일하다.

어떻게 이런 일이 일어날까 이를 알기 위해서 우선 primitives value 와 object 의 차이를 알아야 한다.


자바스크립트에서의 원시값은 7개로 int , string , boolean ,  undefined , symbol, bigint, Null 있다.

원사 값을 제외한 모든 값은 Object로 대표적으로 object literal , array , function ....... 등이 있다.


자바스크립트 엔진의 구성요소에 대해 기억하는가? 콜 스택과 메모리 힙으로 구성되어 있다.
여기서 간단하게 말하자면 원시 값 (primitive type) 은 콜 스택에 저장되고 객체 (reference type) 은 메모리 힙에 저장된다.


콜 스택 그리고 메모리 힙에서 어떻게 원시 값과 객체가 저장되는 지는 아래 글을 참고한다.



위 주소에서 가져왔다.(https://curryyou.tistory.com/276)




콜 스택에서의 객체의 값은 메모리 힙의 객체를 가르키는 주소 값이다.
따라서 me 와 you 같은 콜 스택에서 같은 주소를 가르 키고 있으며 따라서 값인 참조 값 또한 같다. 메모리 힙에서 객체의 정보를 변경할 때는 원시타입에서 와는 다르게 수정하는 것과 같아 me 와 you 는 같은 age 값을 가진다.
간단히 말해 you 는 새로운 객체를 만들지 못하고 me 와 같은 객체를 사용해서 발생하는 문제이다.


 이 문제를 해결 하기 위해선 어떤 방법을 사용 할 수 있을까?
새로운 객체를 만들면 된다.

1
2
3
4
5
6
7
8
9
const me = {
  age: 21,
};
 
const you = Object.assign({}, me);
you.age = 30;
 
console.log(you.age); //30
console.log(me.age); //21
                                  cs 


 me 그리고 you 가 같은 객체를 가르키고 있으므로 새로운 객체를 만들어 주면된다.

객체를 복사하는 방법에는 Object.assign() 을 활용해 새로운 객체를 만들면 된다.

1
2
3
4
5
6
7
8
9
10
const me = {
  age: 21,
  family : ['father' , 'mother']
};
 
const you = Object.assign({}, me);
you.family.push('sister');
 
console.log(you.family);  //father,mother,sister
console.log(me.family);  //father,mother,sister
cs

하지만 이 방법에도 한계는 있다. 

객체 안의 객체에 경우 배열도 객체임을 생각하면 바깥쪽 객체만 다르지 안쪽 객체는 같은 주소값을 가르키기 때문에 객체를 복사하는 방법이 먹히지 않는다.

해결 방안으로는 외부 라이브러리를 사용하는 방법이 있고 나중에 다루도록 하겠다.















댓글

이 블로그의 인기 게시물

Javascript this keyward

javascript 15 switch statement