Today Sangmin Learned
728x90
const num = 2;
const numObj = { num: 2 };

이 코드를 보면, num 변수에는 2가 들어있지만, numObj에는 { num:2 } 오브젝트가 메모리에 들어 있는 주소인 참조값이 할당된다. 예를 들어.. {num:2} 오브젝트의 주소가 x123이라고 한다면 x123이 할당된다는 것이다.

 

배열로 연결해서 생각해 보자.

const array = [
  { id: '1', count: 0 },
  { id: '2', count: 0 },
];

여기서 생성된 오브젝트는 id가 1인 것, id가 2인 것, 그리고 배열 자체의 오브젝트 이렇게 해서 총 3개의 오브젝트가 생성된다.

그렇다면,

const array = [
  { id: '1', count: 0 },
  { id: '2', count: 1 },
];
const array2 = array;
const array3 = [...array];

array2와 array3의 각각의 변수에는 어떤 값이 할당되어 있을까?

array2는 array 변수를 그대로 할당하므로 array의 참조값이 할당이 된다. 반면에 array3은, Spread 연산자를 이용해서 array 배열에 있는 모든 아이템들을 새로운 배열로 가지고 와서 새로운 배열을 만들게 된다. 그래서 완전히 새로운 배열 오브젝트를 가리키게 된다.

 

그러나, 이 Spread 연산자는, 배열 안의 모든 오브젝트 내용들을 일일이 복사해서 새로운 것을 만드는 건 아니고, 오브젝트는 그대로 두고 array 배열을 돌면서 각각의 아이템들의 참조값을 복사하게 된다. 즉 array3에는, array 안에 들어있는 오브젝트들과 동일한 것이 들어있지만, 배열 오브젝트 자체만 새롭게 만들어지는 것이다.

array[0].count = 2;
console.log(array[0]); // {id: '1', count: 2}
console.log(array2[0]); // {id: '1', count: 2}
console.log(array3[0]); // {id: '1', count: 2}

그래서, array의 값을 변경하면 그에 따라 array2와 array3의 값 전부 바뀌게 된다.

이제, array 배열에 새로운 값을 추가한다고 해 보자.

array.push({id: '3', count: 0});
console.log(array.length); // 3
console.log(array2.length); // 3
console.log(array3.length); // 2

array2는 array와 동일한 배열을 가리키고 있으므로 새로운 값이 똑같이 추가되었지만, array3은 새로운, 엄연히 다른 배열 오브젝트이기 때문에 값이 추가가 되지 않는 것이다.

 

결론

Spread 연산자는 얕은 복사(Shallow-cloning)을 한다.

배열 안에 있는 모든 오브젝트, 그리고 그 안에 들어 있을 수 있는 오브젝트들까지 모두 다 하나씩 새로운 것으로 바꿔주는 것이 아니라, 단순히 제일 상위의 배열 껍데기만 새로운 껍데기로 바꿔주고 안의 오브젝트는 예전의 그것의 참조값을 복사해 온다.

 

Spread 연산자를 이용하면, 처음에는 안에 들어있는 내용물들을 복사해 오지만(값은 아니고, 레퍼런스(참조값)만 복사해 오는 것) 배열 자체는 새로운 것을 만들기 때문에 배열에 아이템을 삭제하거나, 추가하면 배열의 내용은 달라질 수 있다.

 

 

profile

Today Sangmin Learned

@steadily-worked

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!