자바스크립트 객체 복사하기 (deep copy)

REASON·2022년 9월 30일
2

STUDY

목록 보기
97/127

객체를 복사한다고 하면 가장 널리 알려져있는 방법으로는 Object.assign과 스프레드 연산자를 통해 복사하는 방법이 있을 것이다.

Object.assign()

const person = {
  name : '아이유',
  age : 30
}

const iu = Object.assign({}, person);

console.log(person); // {name: "아이유", age: 30}
console.log(iu); // {name: "아이유", age: 30}

먼저 Object.assign을 통해 객체를 복사하였다.
제대로 복사되었는지 확인하기 위해 복사한 객체의 value 값을 변경해보자.

const person = {
  name : '아이유',
  age : 30
}

const iu = Object.assign({}, person);

iu.name = "이지은";
console.log(person); // {name: "아이유", age: 30}
console.log(iu); // {name: "이지은", age: 30}

두 객체의 값이 다른 것으로보아 원본 객체가 변화되지 않게 잘 복사되었음을 알 수 있다.

스프레드 연산자

스프레드 연산자를 사용해서도 객체를 복사할 수 있다.

const person = {
  name : '아이유',
  age : 30
}

const iu = { ...person };

Object.assign() 과 마찬가지로 복사한 객체의 값을 바꾸더라도 원본 객체가 변경되지 않는다.

1단계 객체에서는 이와 같은 방법으로 복사할 수 있지만, 문제는 2단 이상으로 이루어진 객체이다.

2단 이상으로 이루어진 객체의 경우 위와 같은 방법을 사용하면 원본 객체가 변경될 수도 있다.

다음 코드를 살펴보자.

const iu = {
  name : '아이유',
  age : 30,
  album : {
    Lilac : "타이틀곡",
    Palette : 2017
  }
}

const iu2 = { ...iu };
iu2.album.Lilac = 2021;

console.log(iu);
console.log(iu2);

iu라는 객체를 iu2에 복사한 후 album Lilac 의 value를 변경하였다.
깊은 복사가 제대로 되었다면 원본 객체가 변경되면 안되지만 결과는 다음과 같았다.

원본까지 함께 변경되어 버린 것이다. 😨

2단 이상의 객체를 깊은 복사하려면 JSON.parse, JSON.stringify 또는 재귀함수를 사용하여 객체를 복사해야 한다.

재귀함수로 객체 깊은 복사

재귀함수를 사용할 때는 언제 재귀함수가 종료되는지 조건을 항상 작성해주어야 한다.

const iu = {
  name : '아이유',
  age : 30,
  album : {
    Lilac : "타이틀곡",
    Palette : 2017
  }
}

const copy = (obj) => {
  if(typeof obj !== "object" || obj === null){
    return obj;
  }
  
  const deepCopyObj = {};
  
  for(let key in obj){
    deepCopyObj[key] = copy(obj[key]);
  }
  
  return deepCopyObj;
}

const iu2 = copy(iu);
iu2.album.Lilac = 2021;

console.log(iu);
console.log(iu2);

재귀함수를 사용해서 원본 객체를 변경시키지 않도록 복사할 수 있다.

JSON.parse, JSON.stringify

두번째는 JSON을 사용한 방법이다.

const iu = {
  name : '아이유',
  age : 30,
  album : {
    Lilac : "타이틀곡",
    Palette : 2017
  }
}

const iu2 = JSON.parse(JSON.stringify(iu));
iu2.album.Lilac = 2021;
console.log(iu);
console.log(iu2);

앞서 사용한 재귀함수보다 코드는 훨씬 더 간단하다.
성능 부분은 복사할 객체에 따라 다르므로 테스트해보고 적절히 사용하는 게 좋을 것 같다.

위 예제 코드로 테스트했을 때 JSON보다 재귀함수가 조금 더 빠른 것(대략 10% 정도)으로 측정됐다.

참고 자료
JavaScript로 Deep Copy 하는 여러 방법

0개의 댓글