JS/JavaScript

#9 자바스크립트 깊은 복사와 얕은 복사 : 차이점과 구현 방법

인생아 2024. 8. 29. 00:09
반응형

자바스크립트에서 객체를 복사하는 것은 자주 사용되는 기능입니다. 하지만 객체를 복사할 때 두 가지 중요한 개념을 이해해야 합니다: **얕은 복사(Shallow Copy)**와 **깊은 복사(Deep Copy)**입니다. 이 두 개념은 복사된 객체가 원본 객체와 어떻게 연결되어 있는지에 따라 큰 차이가 있습니다.

얕은 복사(Shallow Copy)

얕은 복사는 객체의 1단계 깊이 속성만을 복사하고, 그 속성들이 객체나 배열 같은 참조형 데이터일 경우, 참조만 복사합니다. 즉, 얕은 복사된 객체의 중첩된 객체들은 원본 객체의 그것과 동일한 메모리 주소를 가리키게 됩니다.

얕은 복사 예제

const original = {
    name: 'John',
    age: 30,
    address: {
        city: 'New York',
        country: 'USA'
    }
};

const shallowCopy = Object.assign({}, original);

console.log(shallowCopy.address === original.address); // true

위의 예제에서 shallowCopyoriginal 객체의 얕은 복사본입니다. 복사된 객체의 address 속성은 동일한 객체를 참조하고 있으므로, shallowCopy.address === original.addresstrue를 반환합니다.

얕은 복사 방법

  1. Object.assign(): 객체를 얕게 복사하는 데 자주 사용됩니다.
  2. 전개 연산자(Spread Operator): 배열이나 객체를 얕게 복사하는 데 사용됩니다.
// Object.assign 사용
const shallowCopy1 = Object.assign({}, original);

// 전개 연산자 사용
const shallowCopy2 = { ...original };

하지만 이들 방법 모두 중첩된 객체나 배열에 대해서는 참조를 복사하기 때문에, 원본 객체가 변경되면 복사본도 영향을 받습니다.

깊은 복사(Deep Copy)

깊은 복사는 객체의 모든 속성과 중첩된 객체까지 모두 독립적인 복사본을 만드는 것입니다. 깊은 복사된 객체는 원본 객체와 완전히 분리되어 있기 때문에, 원본 객체를 수정해도 복사본에는 아무런 영향이 없습니다.

깊은 복사 예제

const original = {
    name: 'John',
    age: 30,
    address: {
        city: 'New York',
        country: 'USA'
    }
};

// JSON.parse(JSON.stringify()) 방법
const deepCopy = JSON.parse(JSON.stringify(original));

console.log(deepCopy.address === original.address); // false

위의 예제에서 deepCopyoriginal 객체의 깊은 복사본입니다. address 속성은 복사본과 원본이 각각 독립적인 객체를 가리키므로 deepCopy.address === original.addressfalse를 반환합니다.

깊은 복사 방법

  1. JSON.parse(JSON.stringify()): 가장 간단한 방법으로, 대부분의 경우 깊은 복사를 수행할 수 있습니다. 하지만 이 방법은 함수나 undefined 같은 속성을 복사하지 못하는 제한이 있습니다.
  2. 재귀 함수 사용: 보다 완전한 깊은 복사를 위해 재귀적으로 객체의 모든 속성을 복사할 수 있습니다.
function deepCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        return obj.map(deepCopy);
    }

    const copy = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            copy[key] = deepCopy(obj[key]);
        }
    }
    return copy;
}

const deepCopy2 = deepCopy(original);

위의 deepCopy 함수는 객체의 모든 중첩된 속성까지도 완전히 복사합니다.

  1. 라이브러리 사용: Lodash 같은 라이브러리의 _.cloneDeep() 메서드는 객체를 깊게 복사하는 가장 안전하고 강력한 방법 중 하나입니다.
const _ = require('lodash');
const deepCopy3 = _.cloneDeep(original);

결론

자바스크립트에서 객체를 복사할 때는 얕은 복사와 깊은 복사 사이의 차이를 이해하는 것이 중요합니다. 얕은 복사는 빠르고 간단하지만, 중첩된 객체가 원본과 공유될 수 있습니다. 반면, 깊은 복사는 더 복잡하고 자원을 많이 소모할 수 있지만, 복사된 객체가 원본 객체와 완전히 독립적이라는 장점이 있습니다.

어떤 복사 방법을 사용할지는 특정 상황에 따라 달라지며, 객체의 구조와 사용 사례를 고려해 결정해야 합니다.

반응형