자바스크립트를 이용하다보면 기본 객체를 그대로 두고 본 객체를 복사하는 경우가 있다. 기본적으로 객체를 복사하는 방법에는 여러방법이 있겠지만 그중 가장 많이 사용하는 방법 2가지에 대해 알아보도록 하자

 

Object.assign 을 이용한 객체 복사 방법 | 얕은복사
<script>
/* Object.assign 을 이용한 객체복사  */
let obj ={ one : 1 , two : { a : 1, b: 2 } }
let copyObj = Object.assign({}, obj);
copyObj.one=2;
console.log('obj',obj); /* 출력: obj {one:1,two:{a:1,b:2}} */
console.log('obcopyObj',copyObj); /* 출력: copyObj {one:2,two:{a:1,b:2}}  */
</script>

위의 소스는 Object.assign 메서드를 이용하여 처리하였는데 제목을 보면 얕은복사라고 명시해둔 이유가 MDN Web Docs 문서를 보면 아래와 같이 명시되어 있다. 

 

※ Object.assign()은 속성의 값을 복사하기 때문에, 깊은 복사를 수행하려면 다른 방법을 사용해야 합니다.

 

처음 저 설명이 무슨 말이지 한참을 살펴보았는데 해당 문서의 예제를 보니 알 수 있었다. 쉽게 설명하면 복사대상의 기본 객체 뎁스가 1뎁스가 아닌 2뎁스 이상 될경우 깊은 복사를 할 수 없다는것이다. 2뎁스의 객체들은 단순 참조만 하여 복사한 후에 값을 변경하거나 추가할 경우 복사대상의 값 역시 동일하게 생성이 된다. (1뎁스까지 복사가되고 2뎁스는 객체이기때문에 복사가 되면 값인 객체들이 참조만 하는것이다)

 

어떤경우인지는 아래 예제에서 보면 확인이 가능하다 

<script>
/* Object.assign 을 이용한 객체복사  */
let obj ={ one : 1 , two : { a : 1, b: 2 } }
let copyObj = Object.assign({}, obj);
copyObj.one = 11;
copyObj.two.a=2;
copyObj.two.c=3;
copyObj.three = { a:1};
console.log('obj',obj); /* return: obj {one:1,two:{a:2,b:2,c:3}} */
console.log('obcopyObj',copyObj); /* return: copyObj {one:11,two:{a:2,b:2,c:3}, three:{a:1}}  */
console.log(obj.one === copyObj.one); // return: false;
console.log(obj.two.a === copyObj.two.a); // return: true;
console.log(obj.two.c === copyObj.two.c); // return: true;
</script>

위의 결과에서 볼 수 있듯이 two  속성의 값들은 객체이기때문에 참조가 되어 복사된 객체에서 값을 변경하면 복사대상도 같이 변경되거나 추가 되는것을 볼 수 있다. 

 

따라서 결론적으로 완벽한 복사를 위해서는 깊은 복사 방법을 이용해야하는데 방법은 아래와 같다. 

 

JSON.parse + JSON.stringify 을 이용한 객체복사 방법 | 깊은복사
<script>
/* Object.assign 을 이용한 객체복사  */
let obj ={ one : 1 , two : { a : 1, b: 2 } }
let copyObj = JSON.parse(JSON.stringify(obj));
copyObj.one = 11;
copyObj.two.a=2;
copyObj.two.c=3;
copyObj.three = { a:1};
console.log('obj',obj); /* return: obj {one:1,two:{a:1,b:2}} */
console.log('obcopyObj',copyObj); /* return: copyObj {one:11,two:{a:2,b:2,c:3}, three:{a:1}}  */
console.log(obj.one === copyObj.one); // return: false;
console.log(obj.two.a === copyObj.two.a); // return: false;
console.log(obj.two.c === copyObj.two.c); // return: false;
</script>

결과는 주석을 보면 알 수 있드시 복사된 객체는 각각의 값을 가지고 있다. 이처럼 완벽한 객체 복사를 하기 위해서는 바로 위의 방법을 사용하여 처리해야 정상적인 결과를 볼 수 있다.