깊은 복사 (deep copy) : 객체(참조형)를 복사하는데 객체안의 객체까지 .. 전부 복사 된다.
*(참조 관계를 끊는다)*
얕은 복사 (shallow copy) : 객체(참조형)를 복사하는데 객체안의 객체의 경우인 1-depth 객체 부터는 참조된다.
공통 테스트 객체
const sourceObject = {
// 1-depth
traits: {
// 2-depth
first_name: {
value: 'Bob',
source_id: 1,
updated_at: 1623238587468
},
emails_opend_last_30_days: {
value: 33,
source_id: 2,
updated_at: 1623238601089
}
},
cursor: {
url: '/v1/spaces/lgJ4AAjFN4',
has_more: false,
next: ''
}
};
깊은 복사 & 얕은 복사
// 깊은 복사
const newObject1 = JSON.parse(JSON.stringify(sourceObject));
// 얕은 복사
const newObject2 = Object.assign({}, sourceObject);
const newObject3 = { ...sourceObject };
// 깊은 복사 확인
console.log(sourceObject.traits.first_name.source_id); // 1
newObject1.traits.first_name.source_id = 100;
console.log(sourceObject.traits.first_name.source_id); // 1
// 얕은 복사 확인
console.log(sourceObject.traits.first_name.source_id); // 1
newObject2.traits.first_name.source_id = 100;
console.log(sourceObject.traits.first_name.source_id); // 100
newObject3.traits.first_name.source_id = 500;
console.log(sourceObject.traits.first_name.source_id); // 500
깊은 복사 함수로 구현 ☆☆☆
깊은 복사를 JSON.stringify & parse 를 이용하지 않고 다른 방법, 성능이 좋은 방법은 딱히 좋은 방법은 없지만 복사하는 유틸리티 함수를 직접 만드는 방법 뿐이다.
function deepCopyObject(obj) {
const clone = {};
for (const key in obj) {
if (typeof obj[key] == 'object' && obj[key] != null) {
clone[key] = deepCopyObject(obj[key]);
} else {
clone[key] = obj[key]; // clone 객체에 key: value 가 생성됨
}
}
return clone;
}
// 깊은 복사 확인
const newObject4 = deepCopyObject(sourceObject);
console.log(sourceObject.traits.first_name.source_id); // 500
newObject4.traits.first_name.source_id = 1000;
console.log(sourceObject.traits.first_name.source_id); // 500
깊은 복사 함수 활용 및 객체 프로퍼티 오버라이딩
const store = {
user: null,
cart: [],
config: {
multiDevice: false,
lastLoginDate: 'Wed Jun 09 2021 20:46:55 GMT+0900',
}
}
const newObject5 = {
...deepCopyObject(store), // 깊은 복사(요소들만 반환)
config: {
...store.config,
lastLoginDate: new Date(),
}
}
// 객체의 property 는 같은 key가 있으면 맨 아래의 key로 오버라이드 된다.
console.log(newObject5);
// { user: null, cart: {}, config: { multiDevice: false, lastLoginDate: 2021-10-18T14:25:04.251Z } }
const DefaultStyle = {
color: '#fff',
fontColor: '#999',
fontSize: 14,
fontWeight: 200,
};
function createParagraph(config) {
config = { ...DefaultStyle, ...config }
console.log(config);
}
createParagraph({ fontSize: 12 });
// { color: '#fff', fontColor: '#999', fontSize: 12, fontWeight: 200 }