이전 글에서 Array.prototype.slice.call()을 하다가 여기까지 왔는데요
하나를 제대로 알기 위해서는 그와 관련된 여러 가지를 알아야 하는 것 같습니다.
들어가기 전에 원시값과 참조값에 대하여 간단하게 설명드리겠습니다.
이것 또한 깊이 들어가면 들어갈 수 있지만 이 글에서는 다루지 않겠습니다.
원시값은복사할 때 복사된 값을 다른 메모리에 할당하기 때문에 복사를 하더라도 서로에게 영향을 미치지 않습니다.
아래 코드와 같이 a를 b변수에 복사하고 b를 변경한다 하더라도 a가 변경되는 것은 아닙니다.
const a = 1;
let b = a;
b = 2;
console.log(a); // 1
console.log(b); // 2
* 원시값은 String, Number, Boolean, undefined, symbol, null입니다.
참조값은 원시값과 달리 복사를 할 때 그대로 복사되는 것이 아닌 "메모리 주소"의 참조값이 복사됩니다.
아래 코드에서처럼 말이죠
const a = {alphabet : "a"};
let b = a;
b.alphabet = "b";
console.log(a); // {alphabet : "b"}
console.log(b); // {alphabet : "b"}
* 참조값은 Object입니다.
얕은복사 (Shallow copy)
얕은복사의 대표적인 예로는 Object.assign()과 Spread Operator가 있습니다.
console.clear();
const obj = {
a: 1,
b: {
c: 2,
},
};
const newObj = Object.assign({}, obj);
//혹은
const newObj = {...obj};
newObj.b.c = 3
console.log(obj === newObj);// false
console.log(obj.b.c === newObj.b.c )// true
위 코드에서 알 수 있듯 1depth는 false이지만 2depth는 true입니다. 즉 완전히 복사한 것이 아닙니다.
2depth이상까지 완벽하게 복사하는 것이 깊은 복사입니다.
* NodeList, arguments같은 유사 배열 객체들은 배열로 만들어줍니다.
깊은복사 (Deep copy)
1. 재귀 함수
함수 안에서 함수를 반복적으로 사용하여 새로운 object를 반환합니다.
const obj = {
a: 1,
b: {
c: 2,
},
};
function copyObj(obj) {
let result = {};
for(let key in obj) {
if(typeof obj[key] === 'object') {
result[key] = copyObj(obj[key]);
}else{
result[key] = obj[key];
}
}
return result;
}
const newObj = copyObj(obj);
2. JSON.parse(JSON.stringify())
object를 문자열로 만들어 참조를 모두 끊은 후 다시 object 형태로 만들어줍니다.
const obj = {
a: 1,
b: {
c: 2,
},
};
const newObj = JSON.parse(JSON.stringify(obj));
3. lodash - cloneDeep()
라이브러리를 이용하여 만들어줍니다.
const obj = {
a: 1,
b: {
c: 2,
},
};
const newObj = _.cloneDeep(obj);
테스트를 해보면 "재귀 함수 > cloneDeep() > JSON.parse(JSON.stringify())" 순으로 속도가 빠릅니다.
'Front-end > 깊게 파고들기' 카테고리의 다른 글
React-Reudx 정리 (0) | 2022.01.27 |
---|---|
DOM Node, Element 정리 (0) | 2022.01.03 |
Array.prototype.slice.call() 정리, 분석 (0) | 2021.12.25 |
CSR vs SSR (with TTI, TTV, SEO) (0) | 2021.12.16 |
양방향/단방향 데이터 바인딩 (0) | 2021.11.22 |