대가는 결과를 만든다

javascript의 객체 얕은 복사와 깊은 복사 본문

개발/Javascript

javascript의 객체 얕은 복사와 깊은 복사

yunzema 2021. 3. 11. 10:51
반응형

javascript에는 'Number, String, Boolean, Null, Undefined 등'의 원시타입이 있고 'Object, Symbol'의 참조타입이 있다.

 

1. 원시타입의 복사

원시타입의 경우 값을 복사하는 경우 해당 값을 다른 독립적인 메모리 공간에 할당하므로, 복사 값이 원본 값에 영향을 주지 않는 깊은 복사가 수행된다.

 

2. 얕은 복사

참조타입은 참조를 공유하는 복사인 얕은 복사를 하는 경우 복사본의 최상위 속성을 재할당해도 원본 객체에 영향을 끼치지는 않지만, 중첩 객체 속성을 재할당하면 원본 객체에 영향을 끼친다.

 

얕은 복사를 수행하는 코드 : ...전개연산자, Array.prototype.concat(), Array.prototype.slice(), Array.from(), Object.assign(), Object.create()

 

코드 예시)

const ingredientsList = ["noodles", { list: ["eggs", "flour", "water"] }];

const ingredientsListShallowCopy = Array.from(ingredientsList);	//얕은복사

console.log(ingredientsListShallowCopy);
// ["noodles",{"list":["eggs","flour","water"]}]

//중첩 객체 속성 재할당
ingredientsListCopy[1].list = ["rice flour", "water"];

//원본
console.log(ingredientsList[1].list);	//원본도 변함
//[ "rice", flour", "water" ]

//최상위 속성 재할당
ingredientsListShallowCopy[0] = "rice noodles";

//원본의 최상위 속성은 변하지 않음
console.log(ingredientsList[0]); // noodles

//복사본만 변함
console.log(JSON.stringify(ingredientsListShallowCopy));
// ["rice noodles",{"list":["rice flour","water"]}]

//원본의 최상위 속성은 변하지 않고, 중첩 객체 속성만 복사본과 함께 변함
console.log(JSON.stringify(ingredientsList));
// ["noodles",{"list":["rice flour","water"]}]

 

3. 깊은 복사

복사본의 속성이 원본 객체와 같은 참조를 공유하지 않는 복사. 원본/복사본을 변경할 때 서로 영향을 끼치 않는 것을 보장한다.

 

깊은 복사를 수행하는 법 : JSON.parse(JSON.stringify(객체)), 재귀함수를 통한 직접 구현, Lodash의 clonedeep함수 사용

*JSON.parse(JSON.stringify(객체))는 다른 방법에 비해 느리고, 객체가 function인 경우 undefined로 처리한다는 단점이 있음

 

 

참고:

https://developer.mozilla.org/ko/docs/Glossary/Shallow_copy

https://developer.mozilla.org/ko/docs/Glossary/Deep_copy

 

Comments