Javascript
🔍 자바스크립트 깊은 복사 vs 얕은 복사, 제대로 이해하기!
부지런한피로
2025. 3. 16. 05:51
자바스크립트에서 객체나 배열을 복사할 때 **"얕은 복사(Shallow Copy)"**와 "깊은 복사(Deep Copy)" 개념을 정확히 이해하는 것이 중요합니다. 이를 제대로 이해하지 않으면 예상치 못한 버그를 만들 수도 있습니다! 😱
오늘은 얕은 복사와 깊은 복사의 차이점과 실전에서 유용한 복사 방법을 정리해 보겠습니다. 🚀
🧐 1. 얕은 복사(Shallow Copy)란?
얕은 복사는 객체의 1차원 프로퍼티(기본값)는 복사하지만, 중첩된 객체(참조 타입)는 주소값만 복사하는 방식입니다.
✅ 얕은 복사 예제
const original = { name: "Alice", skills: ["JS", "React"] };
const copy = { ...original }; // 얕은 복사
copy.name = "Bob"; // ✅ 변경됨
copy.skills.push("Node.js"); // 😱 원본도 변경됨!
console.log(original);
// { name: "Alice", skills: ["JS", "React", "Node.js"] }
console.log(copy);
// { name: "Bob", skills: ["JS", "React", "Node.js"] }
🔎 왜 원본이 변경되었을까?
- name은 **문자열(기본형)**이므로 값이 복사됨
- skills는 **배열(참조형)**이므로 주소값만 복사됨 → copy.skills를 변경하면 original.skills도 영향을 받음!
✅ 얕은 복사하는 방법
- 객체: { ...obj }, Object.assign({}, obj)
- 배열: [...arr], Array.prototype.slice()
🔥 2. 깊은 복사(Deep Copy)란?
깊은 복사는 중첩된 객체까지 새로운 객체로 완전히 복사하는 방식입니다.
✅ 깊은 복사 예제
const original = { name: "Alice", skills: ["JS", "React"] };
const deepCopy = JSON.parse(JSON.stringify(original)); // 깊은 복사
deepCopy.skills.push("Node.js"); // ✅ 원본은 그대로 유지됨!
console.log(original);
// { name: "Alice", skills: ["JS", "React"] }
console.log(deepCopy);
// { name: "Alice", skills: ["JS", "React", "Node.js"] }
🔎 이 방법의 특징
- JSON.stringify(original) → 객체를 JSON 문자열로 변환
- JSON.parse(...) → JSON을 다시 객체로 변환
- 새로운 객체가 생성되므로 원본과 완전히 독립적!
- 하지만 함수, undefined, Symbol 같은 특수 타입은 복사되지 않음 😵
🚀 3. 가장 안전한 깊은 복사 방법 (lodash 사용하기)
더 복잡한 객체를 복사할 때는 lodash 라이브러리의 cloneDeep()을 사용하면 안정적입니다.
✅ lodash의 cloneDeep() 사용법
const _ = require("lodash");
const original = {
name: "Alice",
skills: ["JS", "React"],
meta: { level: 3 }
};
const deepCopy = _.cloneDeep(original); // 깊은 복사
deepCopy.meta.level = 5; // ✅ 원본에 영향 없음!
console.log(original.meta.level); // 3
console.log(deepCopy.meta.level); // 5
🔎 lodash의 장점
- 객체, 배열, 함수, Map, Set 등 모든 타입을 완벽하게 복사
- 재귀적으로 모든 중첩 객체를 복사
- JSON 방식보다 더 유연하고 안정적
✅ lodash 설치 방법 (Node.js 환경)
npm install lodash
🏆 4. 실전에서 어떤 방법을 선택해야 할까?
복사 방법 | 설명 | 장점 | 단점 |
{ ...obj } | 얕은 복사 | 빠르고 간단 | 중첩 객체는 복사 안됨 |
JSON.parse(JSON.stringify(obj)) | 깊은 복사 | 간단하고 빠름 | 함수, undefined 등 복사 불가 |
_.cloneDeep(obj) | 깊은 복사 | 완벽한 복사 | 추가 라이브러리 필요 |
💡 언제 어떤 방법을 써야 할까?
- 얕은 복사: 1차원 객체만 다룰 때 ({ ...obj }, [...arr])
- JSON 방식 깊은 복사: 단순한 중첩 객체 복사할 때 (JSON.parse(JSON.stringify(obj)))
- lodash cloneDeep: 모든 타입을 완벽하게 복사해야 할 때
🎯 마무리: 안전한 복사 습관을 들이자!
✅ 얕은 복사는 참조값을 공유하므로 조심해야 한다.
✅ 깊은 복사는 중첩된 객체까지 완전히 복사한다.
✅ JSON 방식은 간단하지만 일부 데이터 손실 위험이 있다.
✅ lodash의 cloneDeep()이 가장 강력한 방법이다.