개발자 Saaad
[JavaScript] 얕은 복사, 깊은 복사 본문
저번 포스팅 때는 얕은 비교, 깊은 비교에 대해서 알아봤는데요,
오늘은 얕은 복사, 깊은 복사에 대해서 알아봅시다.
얕은 복사
Spread Operator 를 이용한 얕은 복사
const aArray = [1, 2, 3];
// ... (spread operator)를 이용한 얕은 복사
const bArray = [...aArray, 4];
console.log('aArray', aArray); // [1, 2, 3]
console.log('bArray', bArray); // [1, 2, 3, 4]
console.log('aArray === bArray', aArray === bArray);
// aArray === bArray false
aArray === bArray 가 false 인 이유는 두 배열이 참조하고 있는 주소가 다르기 때문입니다.
Object.assign() 을 이용한 얕은 복사
const cArray = Object.assign([], bArray);
console.log('cArray', cArray);
// [1, 2, 3, 4]
console.log('bArray === cArray', bArray === cArray);
// bArray === cArray false
bArray === cArray 가 false 인 이유는 두 배열이 참조하고 있는 주소가 다르기 때문입니다.
cArray.push([5,6,7]); //[1, 2, 3, Array(3)]
const dArray = [...cArray, 10];
console.log(dArray); // [1, 2, 3, Array(3), 10]
dArray[4].push(8);
console.log(cArray); // [1, 2, 3, Array(4)]
console.log(dArray); // [1, 2, 3, 4, Array(4), 10]
중첩된 배열이나 객체가 있다면 cArray를 shallow copy해서 dArray를 만들고
dArray를 변경했을 때 cArray에 있는 그 중첩된 부분은 따라서 변경되는 것을 볼 수 있습니다.
그래서 얕은 복사 Shallow Copy라고 합니다.(깊은 부분은 복사가 되지 않으니까)
spread operator, Object assign 이외에도 Array.from(), slice 도 얕은 복사를 합니다.
얕은 동결 : Object.freeze()
Object.freeze() 메서드는 객체를 동결합니다. 동결된 객체는 더 이상 변경될 수 없습니다. 즉 동결된 객체는 새로운 속성을
추가하거나 존재하는 속성을 제거하는 것을 방지하며 존재하는 속성의 불변성, 설정 가능성, 작성 가능성이 변경되는 것을
방지하고, 존재하는 속성의 값이 변경되는 것도 방지합니다. 또한, 동결 객체는 그 프로토타입이 변경되는 것도 방지합니다.
freeze()는 전달된 동일한 객체를 반환합니다.
aObject에 값을 할당 후 freeze()메소드를 사용해준 후,
aObject.a 의 값을 변경하려고 하네요.
어떻게 될까요?
aObject 는 얕은 동결을 통해 변경될 수 없는 상태이기 때문에 값이 변하지 않은 모습을 볼 수 있습니다.
이번엔 aObject의 cObject의 a를 변경하려고 합니다.
바뀔까요??
바뀌었습니다! 얕은 동결이 수행되었기 때문에 중첩된 깊은 요소에 대해서는 동결이 되지 않은 것을 확인할 수 있습니다.
깊은 복사
이번에는 깊은 복사를 해보도록 하겠습니다.
1. JSON.Stringify();
const aObject = {
"a": "a",
"b": "b",
"cObject": {"a": 1, "b": 2}
}
const newAObject = JSON.parse(JSON.stringify(aObject));
console.log('aObject:', aObject);
console.log('newAObject:', newAObject);
이번에는 aObject의 cObject.a 값을 변화를 주어 aObject와 newObject의 값의 차이를 살펴보겠습니다.
aObject.cObject.a = 3;
console.log('aObject:', aObject);
console.log('newAObject:', newAObject);
aObject.cObject.a 의 값은 3으로 바뀌었으나, newAObject.cObject.a 의 값은 1로 그대로인 모습입니다.
newAObject 는 깊은 복사를 통해 aObject의 값을 온전히 복사하였고, 중첩된 깊은 요소에 대해서도 aObject로부터 독립적이기
때문에 값이 함께 변하지 않았습니다.
진짜 말그대로 "복사"만 했습니다! 기존 객체로부터 영향을 받지 않습니다.
2. Spread Operator를 이용
// 첫번째 인자는 aObject를 복사
// 두번째 인자에서 aObject.cObject를 새로운 객체로 복사
const newAObject = {...aObject, cObject: {...aObject.cObject}};
aObject.cObject.a = 3;
console.log('aObject:', aObject);
console.log('newAObject:', newAObject);
같은 결과가 나왔습니다!
두번의 얕은 복사를 했다고 생각해도 될 것 같습니다.
첫번째 인자로 aObject를 얕은 복사를 하였고, 두번째 인자로 cObject는 ...aObject.cObject까지 얕은 복사를 한것입니다.
3. lodash 라이브러리를 이용한 깊은 복사
오늘은 깊은복사, 얕은 복사에 대해 알아봤습니다.
감사합니다
'학습 > kakao X goorm 풀스택12회차' 카테고리의 다른 글
[JavaScript] Intersection Observer (0) | 2024.12.08 |
---|---|
[JavaScript] IIFE(Immediately Invoked Function Expression) (1) | 2024.12.07 |
[JavaScript] 얕은 비교, 깊은 비교 (0) | 2024.12.05 |
[JavaScript] null 과 undefined (0) | 2024.12.04 |
[JavaScript] Map, Filter, Reduce (0) | 2024.12.03 |