Object copy

Deep Copy vs Shallow Copy

자바스크립트에서 데이터를 복사하는 방법은 두 가지가 있다.

  • 얕은 복사(Shallow Copy) - 참조만 복사, 객체는 유지

  • 깊은 복사(Deep Copy) - 참조, 객체 모두 복사

좋고 나쁨은 없으며, 개념을 이해하고 원하는 상황에서 사용하는 것이 중요하다.

Shallow Copy

얕은 복사는 객체는 유지하며 참조만 복사한다. 예를 들면 자동차는 그대로 두고 자동차 키만 복제하는 것과 같다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = monster;//shallow copy
console.log(monster, copyMonster);

각각 출력하면 객체의 정보가 잘 나온다.

하지만 이 둘은 동일한 객체이며 단지 참조만 복사된 형태이다.

console.log(monster === copyMonster);//true

사용하는 경우

배열 등을 함수에서 처리할 때 shallow copy를 사용하면 추가 반환 등의 필요가 없다.

const increase = function(arr) {
    for(let i=0; i < arr.length; i++){
        arr[i] += 1;
    }
};

const numbers = [10, 20, 30, 40, 50];
increase(numbers);

console.log(numbers);//[11, 21, 31, 41, 51]

위 코드는 increase 함수에서 추가적인 반환 없이 외부 배열의 값을 변경하는 예제이다. 배열은 하나만 두고 참조를 복사하였기 때문에 원본 배열에 접근하여 작업을 처리할 수 있다.

Deep Copy

Shallow Copy만으로는 배열 혹은 객체가 복제되었다고 보기 어렵다. 일반적으로 복제 혹은 복사라고 하면 참조 뿐만 아니라 대상까지도 복사 되는 경우를 의미할 때가 많으며 코드를 작성할 경우도 이는 마찬가지이다.

수동 복사

직접 객체를 만들고 데이터를 지정하여 복사하는 방법이다. 권장하지 않는다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = {
    no : monster.no,
    name : monster.name,
    type : monster.type
};

console.log(monster === copyMonster);//false

JSON 복사

JSON 변환 명령을 사용한 복사이다.

  • JSON.stringify() - 객체를 JSON 문자열로 변환

  • JSON.parse() - JSON 문자열을 객체로 변환

기존 코드에서는 비교적 간편하게 세부 속성까지 복사가 되므로 자주 사용하는 코드 중 하나이다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = JSON.parse(JSON.stringify(monster));

console.log(monster === copyMonster);//false

Object.assign()

ES6의 Object.assing() 함수를 이용하는 방법이다. 이 명령은 서로 다른 객체를 병합(merge)할 수 있는 명령이지만 빈 객체와 합치면 기존 객체가 깊은 복사가 되는 효과가 발생한다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};

const copyMonster = Object.assign({}, monster);

console.log(monster === copyMonster);//false

rest

구조 분해 할당 문법에서 사용할 수 있는 rest 연산이 있다. 객체에서 특정 항목을 제외한 나머지 항목만 추출하는 명령이지만 이를 이용해도 객체의 깊은 복사가 가능하다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};
const {...copyMonster} = monster;

console.log(monster === copyMonster);//false

rest 연산

rest 연산을 사용하면 특정 항목에 대한 제거가 가능하다.

다음 코드는 monster 객체에서 no를 제외한 나머지 항목을 추출하여 객체를 만드는 코드이다.

const monster = {
    no : 25,
    name : "피카츄",
    type : "전기"
};
const {no, ...copyMonster} = monster;

Last updated