이번에는 자바스크립트 객체를 복사하는 방법에 대해 살펴보겠습니다.
객체 복사에는 얕은복사 (Shallow Copy)가 있고, 깊은 복사 (Deep Copy) 가있습니다.
얕은 복사는 참조하는 것으로서 복사하여 만들어진 객체를 수정하여도 기존 객체도 함께 수정됩니다.
즉 같은것을 참조하고 있는 것이고 깊은 복사는 다른 객체로 생성되어 수정하여도 기존 객체는 영향이 없습니다.
복사에 방법에는 크게 3가지로 나눌 수 있습니다.
1. 첫번째는 복제하지 않고 참조하는 변수만 만들어 얕게 복사합니다.
let sub = {sub: 'sub', time: 1000}
let A = {name: 'Aiden', class: 'A', email: 'aiden@naver.com', item: sub};
let B = A;
console.log(Object.is(A,B)) // true;
console.log(Object.is(A.item, B.item)) // true;
B.name = 'newAiden';
console.log(A.name) // 'newAiden'
B는 A를 얕은복사 한 것으로 같은 것을 가리킵니다.
즉 B를 수정하여도 A가 수정되게됩니다.
2. 두 번째는 Object.assign입니다. 대표 객체는 깊은 복사 하지만 하위 객체는 얕은 복사 합니다.
let sub = {sub: 'sub', time: 1000}
let A = {name: 'Adien', class: 'A', item: sub};
let B = Object.assign({}, A);
console.log(Object.is(A,B)); // false
console.log(Object.is(A.item, B.item)); // true
대표 객체인 A와 B는 다르다고 하지만 하위 객체는 같은 값입니다.
3. 세 번째는 대표 객체뿐만 아니라 하위 객체도 깊은 복사 하는 방법입니다.
이 방법에는 3가지가 있습니다.
- JSON.stringify()
let sub = {sub: 'sub', time: 1000}
let A = {name: 'Adien', class: 'A', item: sub};
let B = JSON.parse(JSON.stringify(A));
console.log(Object.is(A,B)); // true
console.log(Object.is(A.item, B.item)); // true
JSON.stringify()는 객체를 json 문자열로 변환하는데 그 과정에서 객체와의 참조가 모두 끊어진다.
이 방법은 사용하기는 쉽지만 다른 방법에 비해 아주 느리다고 알려져 있다.
- 재귀 함수를 이용한 복사
const mainObj = {
a : 1,
o : {
b : 2
}
};
function deepCopyObj(targetObj) {
const result = {};
for (let key in targetObj) {
if (typeof targetObj[key] === 'object') {
result[key] = deepCopyObj(targetObj[key]);
} else {
result[key] = targetObj[key];
}
}
return result;
}
const deepCopiedObj = deepCopyObj(mainObj);
console.log(Object.is(mainObj, deepCopiedObj)) // false;
console.log(Object.is(mainObj.o.b, deepCopiedObj.o.b)) // false;
- 라이브러리 사용
lodash 라이브러리를 사용하면 깊은 복사를 더 쉽게 할 수 있다.
const deepCopiedObj = _.cloneDeep(mainObj);
console.log(Object.is(deepCopiedObj, mainObj)); // false