본문 바로가기

JavaScript

얕은 복사 & 깊은 복사

배열이나 객체를 사용할 때 특정 배열을 복사하거나 새롭게 만들기 위해서 복사를 하는 경우가 있다. 

이때 경우에 따라 예상치 못한 작업이 발생하는데, 이것이 얕은 복사로 인한 문제들이다. 

 

얕은 복사

주소값까지만 복사를 해주는 것이 얕은 복사이다. 

const object = {
  name: "잉여",
  age: "28",
};

const newObject = { ...object };

console.log(newObject);

객체를 복사할 때 많이 사용하는 방식이 spread 연산자를 활용하는 방식이다. 

이렇게 하면 object의 주소값만 복사하는 것이 아닌 내부값을 새롭게 복사하기 때문에 newObject의 name이 변경되더라도 object의 name은 변화가 없다. 

 

이렇게보면 이 행위 자체가 얕은 복사가 아니라고 생각할 수 있다. 

const object = {
  name: "잉여",
  age: "28",
  hobby: ["board", "computer"],
};

const newObject = { ...object };

newObject.hobby.push("baking");

console.log(object);
console.log(newObject);

object 안에 배열이 있다고 생각해보자 이때 newObject에게 새로운 취미를 추가하면 object는 어떻게 될까? 

둘다 들어가게 된다!! 

이유는 object를 spread 연산자를 활용해서 newObject를 만들었다고 해도 object의 hobby 역시 객체이기 때문에 주소값으로 되어있다. 그렇기 때문에 newObject의 hobby는 object의 hobby의 주소값을 가지게 된다. 

 

이런 문제로 예상치 못한 버그가 발생하게 된다. 

 

깊은 복사 

실제 데이터까지 복사하는 것을 깊은 복사라고 한다. 

const object = {
  name: "잉여",
  age: "28",
  hobby: ["board", "computer"],
};

const newObject = JSON.parse(JSON.stringify(object));

객체를 깊은 복사를 할 때는 JSON을 사용하면 된다. 

JSON.stringify 함수는 객체를 JSON 형식의 문자열로 변경시켜준다. 이때 object의 주소값은 모두 깨지게 된다. 

그리고 JSON.parse 함수를 사용해서 JSON 형식의 문자열을 객체로 변경시켜주면 새로운 주소에 할당된다. 

 

단순하게 생각해도 문자열을 객체로 만들기 때문에 주소값이 똑같다는 것이 말이안된다. 

객체를 복사할 때 내부 값에 또다른 객체가 있는지 잘 판단해서 복사를 하는 것이 중요하다. 

반응형

'JavaScript' 카테고리의 다른 글

Transition & Animation 이벤트  (3) 2024.10.09
스크롤 위치에 따른 오브젝트 조작  (1) 2024.09.29
Object  (1) 2024.09.21
호이스팅  (1) 2024.08.21
함수 스코프, 블록 스코프  (1) 2024.08.14