객체를 복사한다고 하면 가장 널리 알려져있는 방법으로는 Object.assign과 스프레드 연산자를 통해 복사하는 방법이 있을 것이다.
const person = {
name : '아이유',
age : 30
}
const iu = Object.assign({}, person);
console.log(person); // {name: "아이유", age: 30}
console.log(iu); // {name: "아이유", age: 30}
먼저 Object.assign을 통해 객체를 복사하였다.
제대로 복사되었는지 확인하기 위해 복사한 객체의 value 값을 변경해보자.
const person = {
name : '아이유',
age : 30
}
const iu = Object.assign({}, person);
iu.name = "이지은";
console.log(person); // {name: "아이유", age: 30}
console.log(iu); // {name: "이지은", age: 30}
두 객체의 값이 다른 것으로보아 원본 객체가 변화되지 않게 잘 복사되었음을 알 수 있다.
스프레드 연산자를 사용해서도 객체를 복사할 수 있다.
const person = {
name : '아이유',
age : 30
}
const iu = { ...person };
Object.assign() 과 마찬가지로 복사한 객체의 값을 바꾸더라도 원본 객체가 변경되지 않는다.
1단계 객체에서는 이와 같은 방법으로 복사할 수 있지만, 문제는
2단 이상
으로 이루어진 객체이다.
2단 이상으로 이루어진 객체의 경우 위와 같은 방법을 사용하면 원본 객체가 변경될 수도 있다.
const iu = {
name : '아이유',
age : 30,
album : {
Lilac : "타이틀곡",
Palette : 2017
}
}
const iu2 = { ...iu };
iu2.album.Lilac = 2021;
console.log(iu);
console.log(iu2);
iu라는 객체를 iu2에 복사한 후 album Lilac 의 value를 변경하였다.
깊은 복사가 제대로 되었다면 원본 객체가 변경되면 안되지만 결과는 다음과 같았다.
원본까지 함께 변경되어 버린 것이다. 😨
2단 이상
의 객체를 깊은 복사하려면 JSON.parse, JSON.stringify 또는 재귀함수를 사용하여 객체를 복사해야 한다.
재귀함수를 사용할 때는 언제 재귀함수가 종료되는지 조건을 항상 작성해주어야 한다.
const iu = {
name : '아이유',
age : 30,
album : {
Lilac : "타이틀곡",
Palette : 2017
}
}
const copy = (obj) => {
if(typeof obj !== "object" || obj === null){
return obj;
}
const deepCopyObj = {};
for(let key in obj){
deepCopyObj[key] = copy(obj[key]);
}
return deepCopyObj;
}
const iu2 = copy(iu);
iu2.album.Lilac = 2021;
console.log(iu);
console.log(iu2);
재귀함수를 사용해서 원본 객체를 변경시키지 않도록 복사할 수 있다.
두번째는 JSON을 사용한 방법이다.
const iu = {
name : '아이유',
age : 30,
album : {
Lilac : "타이틀곡",
Palette : 2017
}
}
const iu2 = JSON.parse(JSON.stringify(iu));
iu2.album.Lilac = 2021;
console.log(iu);
console.log(iu2);
앞서 사용한 재귀함수보다 코드는 훨씬 더 간단하다.
성능 부분은 복사할 객체에 따라 다르므로 테스트해보고 적절히 사용하는 게 좋을 것 같다.
위 예제 코드로 테스트했을 때 JSON보다 재귀함수가 조금 더 빠른 것(대략 10% 정도)으로 측정됐다.