얕은 비교
숫자, 문자열 등 원시 자료형은 값을 비교한다.
배열, 객체 등 참조 자료형은 값 혹은 속성을 비교하지 않고, 참조되는 위치를 비교한다.
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
console.log(obj1 === obj2); // false
값 대신 참조 위치를 비교하기 때문에 false가 나온다.
깊은 비교
얕은 비교와 달리 깊은 비교는 객체의 경우에도 값으로 비교한다.
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true
JSON.stringify()를 사용한다.
얕은 복사
객체의 최상위 프로퍼티만 복사하는 방법으로, 중첩된 객체는 참조값으로 유지된다.
// 스프레드 연산자를 통한 복사
const aArray = [1,2,3];
const bArray = [...aArray, 4];
console.log('aArray', aArray); // aArray [ 1, 2, 3 ]
console.log('bArray', bArray); // bArray [ 1, 2, 3, 4 ]
console.log('aArray === bArray', aArray === bArray); // aArray === bArray false
// Object.assign()을 통한 복사
const cArray = Object.assign([],bArray);
console.log(‘cArray’, cArray); // cArray [ 1, 2, 3, 4 ]
console.log(‘bArray === cArray’, bArray === cArray); // bArray === cArray false
왜 얕은 복사인가?
다음과 같이 aArray 배열을 복사하고 10을 추가한 bArray가 있다고 하자. 각각 [ 1, 2, 3, [ 4, 5, 6 ] ] [ 1, 2, 3, [ 4, 5, 6 ], 10 ] 값이 출력되는 것을 확인할 수 있다.
이때 bArray의 중첩된 배열의 값에 7을 추가하고 aArray와 bArray를 다시 출력해 본다. 오잉? 분명히 bArray의 값만 변경했음에도 불구하고 aArray의 값도 변경되었다. 왜 그럴까?
중첩된 객체는 원래의 참조값을 유지한다. 위의 코드를 비교해 보면 aArray와 bArray를 비교했을 때는 false가 나오는 반면, 중첩된 부분인 aArray[3]과 bArray[3]을 비교했을 때는 true가 나오는 것을 확인할 수 있다.
그래서 값을 변경했을 때 같이 변경되는 것이고, 이렇게 깊은 부분까지는 복사가 안되니까 얕은 복사라고 하는 것이다.
얕은 동결
const aObject = {
"a" : "a",
"b" : "b",
"cObject" : {"a" : 1, "b" : 2}
}
Object.freeze(aObject);
aObject.a = 'c';
console.log(aObject.a); // a
Object.freeze()로 동결된 객체는 더 이상 변경될 수 없다. 그래서 a를 ‘c’로 변경했음에도 변경되지 않고 그대로 a가 출력된다.
const aObject = {
"a" : "a",
"b" : "b",
"cObject" : {"a" : 1, "b" : 2}
}
Object.freeze(aObject);
aObject.cObject.a = 10;
console.log(aObject.cObject.a); // 10
하지만 얕은 동결인 만큼 객체 안에는 동결시키지 못한다. 동결됐음에도 cObject의 a값이 10으로 변경된 것을 확인할 수 있다.
깊은 복사
얕은 복사와 다르게 중첩된 객체까지 모두 복사하여 완전히 독립적인 복사본을 만드는 것이다.
const aObject = {
"a" : "a",
"b" : "b",
"cObject" : {"a" : 1, "b" : 2}
}
const newAObject = JSON.parse(JSON.stringify(aObject));
console.log('aObject', aObject); // aObject { a: 'a', b: 'b', cObject: { a: 1, b: 2 } }
console.log('newAObject', newAObject); // newAObject { a: 'a', b: 'b', cObject: { a: 1, b: 2 } }
aObject.cObject.a = 3;
console.log('aObject', aObject); // aObject { a: 'a', b: 'b', cObject: { a: 3, b: 2 } }
console.log('newAObject', newAObject); // newAObject { a: 'a', b: 'b', cObject: { a: 1, b: 2 } }
얕은 복사와 다르게, 배열이나 객체로 중첩된 부분도 처리를 해준다. 그래서 중첩된 부분의 값을 변경해도 같이 변경되지 않는 것을 확인할 수 있다.
'프로그래밍 언어 > JavaScript' 카테고리의 다른 글
[JS] Intersection observer (0) | 2024.04.27 |
---|---|
[JS] 함수 선언식과 표현식, 즉시 실행 함수(IIFE) (0) | 2024.04.26 |
[JS] 클로저 (2) | 2024.04.25 |
[JS] 이벤트 루프 (0) | 2024.04.25 |
[JS] call, apply, bind 메서드 (0) | 2024.04.25 |