객체에 값을 저장하면 메모리 주소가 객체에 담긴다.
const a = {
name: 'tom',
age: 22
};
원시 타입인 변수끼리 비교한다면, 값 자체를 비교하고,
객체 타입인 변수끼리 비교한다면, 참조 값을 비교한다.
console.log(a === b); // false: 각각 객체를 할당했기 때문에 참조 값 다름
console.log(a.name === b.name); // true: 값 자체 비교
기본적으로 복사는 주소값을 복사해 오는 것이기 때문에 원치 않은 결과를 야기할 수 있다.
let a = { name: "tom" };
a = { name: "jude" };
const b = a;
console.log(b);
console.log(b); // name: jude
따라서 얇은 복사와 깊은 복사를 알고 적절히 이용할줄 알아야 한다.
얇은 복사는 1 depth 까지의 복사를 의미가 하고 깊은 복사는 값 자체의 복사를 의미한다.
// assign을 활용한 2차원 배열의 얇은 복사
let a = 1;
let b = a;
b = 2;
console.log(a); // 1
console.log(b); // 2
console.log(a === b); // false
const obj = {
a: 1,
b: {
c: 2
}
};
const newObj = Object.assign({}, obj);
newObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(obj.b.c === newObj.b.c); // true
// 전개연사자의 2차원 배열 얇은 복사
const obj = {
a: 1,
b: {
c: 2,
},
};
const newObj = { ...obj };
newObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(obj.b.c === newObj.b.c); // true
깊은 복사를 구현하려면 원칙적으로 재귀함수를 이용해서 모든 depth를 순회하는 함수를 사용하여 깊은 복사를 한다.
function deepCopy(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
let copy = {};
for (let key in obj) {
copy[key] = deepCopy(obj[key]);
}
return copy;
}
const obj = {
a: 1,
b: {
c: 2,
},
func: function () {
return this.a;
},
};
const newObj = deepCopy(obj);
newObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 }, func: [Function: func] }
console.log(obj.b.c === newObj.b.c); // false
그 외에 lodash나 json parse를 이용한 방식이 있다.
참조: