객체를 참조에 의해 복사할 때 발생하는 주요 오류는 예기치 않은 변경이다.
이는 한 객체의 속성을 수정할 때,
해당 객체의 참조를 가진 다른 객체들도 영향을 받기 때문에 발생한다.
예상치 못한 버그가 발생하거나 데이터가 의도치 않게 수정될 수 있다.
1. 얕은 복사(Shallow Copy) 사용
스프레드 연산자 { ...original }나 Object.assign()을 사용해 얕은 복사 가능.
얕은 복사는 최상위 객체의 참조를 끊어 주지만,
중첩된 객체는 여전히 참조가 공유되기 때문에 완벽한 해결책이 아니다.
🖥️ javascript
const original = { name: "Alice", age: 25, address: { city: "Wonderland" } };
const copy = { ...original };
copy.age = 26;
console.log(original.age); // 25 (변경되지 않음)
copy.address.city = "New Wonderland";
console.log(original.address.city); // "New Wonderland" (참조가 공유됨)
위 코드에서 age는 독립적으로 변경되지만,
address.city는 참조가 공유되어 여전히 original에도 영향을 준다.
2. 깊은 복사(Deep Copy) 사용
깊은 복사는 객체의 모든 중첩 구조까지 새로운 객체로 복사해,
참조가 완전히 끊긴다. 이를 위해 몇 가지 방법을 사용할 수 있다.
🖥️ javascript
const original = { name: "Alice", address: { city: "Wonderland" } };
const copy = structuredClone(original);
copy.address.city = "New Wonderland";
console.log(original.address.city); // "Wonderland" (영향을 받지 않음)
🖥️ javascript
const original = { name: "Alice", address: { city: "Wonderland" } };
const copy = JSON.parse(JSON.stringify(original));
copy.address.city = "New Wonderland";
console.log(original.address.city); // "Wonderland" (영향을 받지 않음)
🖥️ javascript
const _ = require('lodash');
const original = { name: "Alice", address: { city: "Wonderland" } };
const copy = _.cloneDeep(original);
copy.address.city = "New Wonderland";
console.log(original.address.city); // "Wonderland" (영향을 받지 않음)
❓lodash 예시 코드는 왜 변수명을 언더바로 쓸까?
➡️ 객체 복사 시 참조가 공유됨으로 인해 발생할 수 있는 문제를 방지하려면,
단순한 얕은 복사가 아닌 깊은 복사가 필요하다. 최신 자바스크립트의 structuredClone(), JSON.parse(JSON.stringify()) 방법, 또는 lodash의 cloneDeep() 같은 라이브러리를 사용해 안전하게 객체의 참조를 분리할 수 있다.