기술면접을 준비하는 과정에서 자바스크립트의 얕은 복사와 깊은 복사라는 주제에 대해 다시 공부해야 겠다고 생각하고, 이 주제에 대해 다시 작성하기로 하였다.
프로그래밍 언어에서 값을 저장하기 위해 변수를 사용한다. 복사를 만든다는 것은 같은 값을 갖는 새로운 변수를 초기화하는 것을 의미한다. 하지만 얕은 복사와 깊은 복사의 경우에는 주의해야 할 점이 있다.
얕은 복사는 특정 값 또는 하위 값들이 여전히 원본 변수에 연결되어 있는 상태를 의미한다.
기본적으로 객체의 필드가 다른 객체를 참조하고 있다면 동일한 메모리 주소를 공유하게 된다.
const product = {
name: '키보드',
price: 100000
};
const copyOfProduct = product; // 1️⃣
console.log(product, 'product');
/*
{ name: '키보드', price: 100000 } 'product'
*/
copyOfProduct.price = 200000; // 2️⃣
console.log(product, 'product'); // 3️⃣
/*
{ name: '키보드', price: 200000 } 'product'
*/
product 변수가 참조하는 객체의 주소값을 copyOfProduct 변수에 할당하였다.product 변수와 copyOfProduct 변수는 동일한 객체를 참조한다.
copyOfProduct 변수가 참조하는 객체의 price 프로퍼티의 값을 변경한 결과, 3️⃣에서 product 변수가 참조하는 객체의 price 프로퍼티의 값도 변경된 것을 확인할 수 있다.
product 변수가 참조하는 객체와 copyOfProduct 변수가 참조하는 객체가 같기 때문이다.얕은 복사는 객체의 주소값만 복사한다는 것을 알 수 있다.
깊은 복사는 원본 객체의 모든 속성들을 복사하여 별도의 메모리 공간에 할당하고, 새로운 객체가 해당 메모리 공간을 참조하게 한다.
깊은 복사를 사용하면 원본 객체의 값이 변경될 걱정 없이 사본 객체를 생성할 수 있다.
깊은 복사를 생성하는 방법에는 JSON.parse()와 JSON.stringify()를 사용하는 가장 기본적인 방법이 있다.
const product = {
name: '키보드',
price: 100000
};
const copyOfProduct = JSON.parse(JSON.stringify(product)); // 1️⃣
console.log(product, 'product');
console.log(copyOfProduct, 'copyOfProduct');
/*
{ name: '키보드', price: 100000 } 'product'
{ name: '키보드', price: 100000 } 'copyOfProduct'
*/
copyOfProduct.name = '기계식키보드'; // 2️⃣
copyOfProduct.price = 200000; // 2️⃣
console.log(product, 'product'); // 3️⃣
console.log(copyOfProduct, 'copyOfProduct'); // 3️⃣
/*
{ name: '키보드', price: 100000 } 'product'
{ name: '기계식키보드', price: 200000 } 'copyOfProduct'
*/
product 변수가 참조하는 객체를 복사하여 새로운 메모리 공간에 할당하고, copyOfProduct 변수가 해당 메모리 공간을 참조하게 하였다.
copyOfProduct 변수가 참조하는 객체의 name, price 프로퍼티의 값을 수정했음에도, 3️⃣에서 product 변수가 참조하는 객체와 copyOfProduct 변수가 참조하는 객체가 서로 다르다는 것을 알 수 있다.
깊은 복사는 원본 객체를 복사해 별도의 메모리 공간에 새롭게 할당하고, 그 주소값을 변수에 할당한다는 것을 알 수 있다.