오도원입니다.

건강과 행복을 위하여

Development/Javascript

Javascript. 진짜로 Deep Copy하기

오도원공육사 2020. 8. 10. 11:22
반응형

Javascript에서 Array 또는 Object를 복사하는 방법에 대해서 알아보자.

 

일단 결론부터 말하면 다음과 같이 하면된다.

let deepArr = JSON.parse(JSON.stringify(arr1));

 

다음은 자세한 설명이다.

1. 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)

얕은 복사는 alias로 인해 같은 주소를 공유하기 때문에 복사한 객체를 변경하면 기존 객체도 같이 변경되는 문제가 발생할 수 있다.

 

따라서 복사를 할 때는 깊은 복사를 해야 추후 예상치 못한 문제를 방지할 수 있다.

2. 자바스크립트에서의 복사

1) 얕은 복사 - 대입

let arr1 = [
    {"name": "오도원", "job": "player"}, 
    {"name": "오도투", "job": "player"}, 
    {"name": "오도쓰리", "job": "coach"}
];

위와 같은 객체를 얕은 복사해보자.

let arr2 = arr1;

arr2[0].name = '육도원';
console.log(arr2);
console.log(arr1);

arr2[0]의 name을 변경하니깐 arr1이 함께 변경된 것을 확인할 수 있다. 이것이 얕은 복사에서의 alias 문제이다.

 

2) 얕은 복사 - slice

이 문제는 slice를 이용해서 복사할 때도 발생한다.

let arr3 = arr1.slice(0, 1);

slice를 이용해서 arr1의 첫번째 원소를 슬라이싱한다.

arr3[0].name = '칠도원';

그러고 슬라이싱한 arr3를 변경한다.

arr1이 같이 변경된다.

 

slice를 해도 얕은 복사가 발생한다.

대입으로 복사한 객체는 완전히 똑같다. 그러나 slice로 복사한 객체는 겉은 다르지만 안에 object는 얕은 복사되었기 때문에 true가 출력된 것을 볼 수 있다.

 

3. 깊은 복사

그래서 자바스크립트에서 제대로 깊은 복사를 하기 위해서는 JSON.stringify()와 JSON.parse()를 사용한다.

let deepArr = JSON.parse(JSON.stringify(arr1));

JSON.stringify()로 string으로 타입캐스팅 후 다시 JSON.parse로 object로 바꾼다. 그러면 완전히 다른 객체로 생성되면서 깊은 복사를 할 수 있다.

내부 object까지 완전히 깊은 복사되었다. 

alias 문제가 발생하지 않는다.

 

반응형