JavaScript에서 객체 복사는 단순해 보이지만 복잡한 주제입니다. 특히 데이터의 무결성 유지, 부작용 방지, 그리고 예측 가능한 코드 작성에 중요한 역할을 합니다. 이 글에서는 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)의 개념을 심도 있게 살펴보고, 각 방법의 장단점과 적절한 사용 시기를 알아보겠습니다.
얕은 복사는 객체의 최상위 속성만을 새로운 객체에 복사합니다. 이는 중첩된 객체나 배열의 경우 원본 객체와 동일한 참조를 공유하게 됩니다.
const original = {
name: "Alice",
age: 30,
address: {
city: "Seoul",
country: "South Korea"
},
hobbies: ["reading", "coding"]
};
// 얕은 복사 수행
const shallowCopy = Object.assign({}, original);
// 또는 스프레드 연산자 사용
// const shallowCopy = { ...original };
shallowCopy.name = "Bob";
shallowCopy.address.city = "Busan";
shallowCopy.hobbies.push("gaming");
console.log(original.name); // "Alice" (변경되지 않음)
console.log(original.address.city); // "Busan" (변경됨!)
console.log(original.hobbies); // ["reading", "coding", "gaming"] (변경됨!)
이 예제에서 name
과 같은 원시 타입 속성은 독립적으로 복사되지만, address
와 hobbies
와 같은 객체나 배열은 참조만 복사됩니다. 따라서 이들을 수정하면 원본 객체에도 영향을 미칩니다.
깊은 복사는 객체의 모든 수준에서 새로운 복사본을 생성합니다. 이는 중첩된 객체와 배열을 포함해 모든 데이터 구조를 완전히 독립적으로 복제합니다.
const original = {
name: "Alice",
age: 30,
address: {
city: "Seoul",
country: "South Korea"
},
hobbies: ["reading", "coding"]
};
// JSON을 이용한 깊은 복사
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.name = "Charlie";
deepCopy.address.city = "Incheon";
deepCopy.hobbies.push("traveling");
console.log(original.name); // "Alice" (변경되지 않음)
console.log(original.address.city); // "Seoul" (변경되지 않음)
console.log(original.hobbies); // ["reading", "coding"] (변경되지 않음)
이 방법은 간단하지만 함수, undefined
, Symbol
, 순환 참조 등을 처리하지 못하는 한계가 있습니다.
데이터 독립성:
메모리 사용:
성능:
사용 사례:
...
)Object.assign()
Array.from()
(배열의 경우)JSON.parse(JSON.stringify())
)_.cloneDeep()
)function deepCopy(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(deepCopy);
}
const copiedObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copiedObj[key] = deepCopy(obj[key]);
}
}
return copiedObj;
}
// 사용 예
const original = { a: 1, b: { c: 2 } };
const copy = deepCopy(original);
이 함수는 기본적인 깊은 복사를 수행하지만, 순환 참조나 특수한 객체 타입(예: Date
, RegExp
)에 대해서는 별도의 처리가 필요합니다.
얕은 복사 사용:
깊은 복사 사용:
JavaScript에서 객체 복사는 단순해 보이지만 많은 고려사항이 필요한 주제입니다. 이 가이드를 통해 얕은 복사와 깊은 복사의 개념을 명확히 이해하고, 프로젝트에 가장 적합한 방법을 선택할 수 있기를 바랍니다.