객체를 복사하는 방법은 여러가지가 있다.
사용처에 따라서 알맞는 방식을 고르면 되는데, 최근에 structuredClone()
이라는 메서드를 알게 되면서 각각의 복사 방법이 동작하는 방식에 대해서 다시 찾아보게 되었다.
우선, 여러가지 객체 복사 방식은 복사되는 깊이에 따라 얕은 복사, 깊은 복사로 흔히 나뉜다.
하지만 이렇게 이분화 하기에는 복사 방식 마다 그 차이점이 있기 때문에, 3가지로 나누는게 적절하다고 본다.
1. Shallow Copy
- 참조 값만 복사되는 경우
2. Deep + Shallow Copy
- 대표 객체는 복사, 하위 객체는 참고만 함
3. Deep Copy
- 대표 + 하위 객체 모두 복사하는 방식
복사할 object
const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObject = object;
const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObj0 = originalObj;
// 원본을 변경하면 복사본도 변경되고,
originalObj.name = "joy";
console.log(newObj0.name); // joy
// 복사본을 변경하면 원본도 변경된다.
newObj0.info.age = 32;
console.log(originalObj.info.age); // 32
2. Object.assign
사용하기const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObj1 = Object.assign({}, originalObj);
// 1depth 프로퍼티는 변경해도 서로에게 영향 X
originalObj.name = "joy";
console.log(newObj1.name); // jiwon
// 2depth 프로퍼티는 변경할 시, 원본/복사본 둘다 변경됨
newObj1.info.age = 32;
console.log(originalObj.info.age); // 32
{ ...originalObj }
const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObj2 = { ...originalObj };
// 1depth 프로퍼티는 변경해도 서로에게 영향 X
originalObj.name = "joy";
console.log(newObj2.name); // jiwon
// 2depth 프로퍼티는 변경할 시, 원본/복사본 둘다 변경됨
newObj2.info.age = 32;
console.log(originalObj.info.age); // 32
JSON.parse(JSON.stringify(obj))
const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObj3 = JSON.parse(JSON.stringify(originalObj));
structuredClone()
사용하기const originalObj = {
id: 1,
name: "jiwon",
info: {
age: 20,
gender: "female",
birthday: new Date(1999, 1, 1),
etc: new Set([1, 2, 3, 4, 5]),
},
};
const newObj4 = structuredClone(originalObj);
JSON
사용 vs structuredClone()
공통점
시간 비교
// 크기가 큰 객체 생성
const largeObj = {};
const size = 10000000;
for (let i = 0; i < size; i++) {
largeObj[`prop${i}`] = i;
}
// structuredClone()의 실행 시간 측정
const startTime = performance.now();
const clonedObj = structuredClone(largeObj);
const endTime = performance.now();
const executionTime1 = endTime - startTime;
console.log("structuredClone() 실행 시간:", executionTime1);
// JSON.parse(JSON.stringify())의 실행 시간 측정
const startTime2 = performance.now();
const clonedObj2 = JSON.parse(JSON.stringify(largeObj));
const endTime2 = performance.now();
const executionTime2 = endTime2 - startTime2;
console.log("JSON.parse(JSON.stringify()) 실행 시간:", executionTime2);
Reference
https://soobing.github.io/javascript/deep-copying-objects-with-the-structuredclone-api/