Deep Copy VS Shallow Copy

Jnnsu·2023년 12월 10일
1
post-thumbnail

깊은 복사(Deep Copy) - 자료형의 값 복사


Heap 영역에 새로운 메모리 공간을 생성하여 실제 값을 복사한다.

let originalValue = 100;
let newValue = originalValue;

originalValue = 200;

console.log(originalValue);
console.log(newValue);

1열에서 originalValue에 100의 값이 들어가고,
2열에서 newValue에 100이라는 값이 복사되어, 아래 그림과 같이 두개의 변수 OriginalValue, NewValue는 완전히 독립적인 상태가 된다.

이 상태에서 4열에 따라 originalValue의 값을 200으로 변경하면, originalValue 값만 200이 된다.

이렇게 두 변수가 완전히 독립성을 갖는 것을 '값 복사' 또는 '깊은 복사' 라고 한다.
값을 복사하고 변경했을 때, 다른 값에 전혀 영향을 주지 않는다.


얕은 복사(Shallow Copy) - 객체의 참조 복사


original 인스턴스를 생성하면 Stack 영역에 참조값이, Heap 영역에 실제값이 저장이 된다.
그리고 얕은 복사를 통해 객체를 복사했기 때문에 copy 인스턴스는 original 인스턴스가 참조하고 있는 Heap 영역의 참조값을 동일하게 바라보고 있는 상태가 된다.

객체에 변수를 저장하면, 실제 값을 저장하는 것이 아니라 객체를 메모리 어딘가에 만들고, 객체의 참조(위치값) 를 저장하게 된다.
따라서 객체(배열 포함)의 경우 =를 이용하여 복사하면, 참조 복사만 가능하다.

let originalArray = [1,2,3,4];
let newArray = originalArray;

originalArray[0] = 200;

console.log(originalArray);
console.log(newArray);

1열에서 배열 originalArraydp [1,2,3,4]를 저장하는 과정은 다음과 같다.
주소값 0x10에 [1,2,3,4]를 저장하고, 객체 originalArray는 '0x10'위치를 참조.

이때 2열에 따라 참조되는 위치값 '0x10'이 복사된다.

4열에서 originalArray[0]=200;을 실행하면, 참조되는 위치 0x10의 값이 변경된다.

originalArray와 newArray는 같은 메모리 위치를 참조하게 된다.
따라서 두 배열은 독립적이지 않다. 이것을 '참조 복사' 또는 '얕은 복사'라고 한다.


복사 방법

  1. spread(...) 연산자를 통한 복사
    • 복사한 객체 자체는 깊은 복사이지만 내부의 객체는 얕은 복사가 진행된다.
let origin = { 
	a: 1, b: { c: 2 } 
}; 
let copy = {...origin} 
copy.b.c = 3 

console.log(origin === copy) // false 
console.log(origin.b.c === copy.b.c) // true
  1. Object.assign() 메소드를 통한 복사
    • Object.assign()을 이용하면 객체 자체는 깊은 복사가 수행되지만, 2차원 이상의 객체는 얕은 복사가 수행된다. 아래 예시에서 객체는 서로 다른 주소를 참조하고 있어 깊은 복사가 이루어졌지만 내부의 객체는 같은 주소를 참조하고 있다.
/* Object.assign(생성할 객체, 복사할 객체) */
let origin = {
    a: 1,
    b: { c: 2 }
};
let copy = Object.assign({}, origin);
copy.b.c = 3

console.log(origin === copy) // false
console.log(origin.b.c === copy.b.c) // true

참조:
https://zzang9ha.tistory.com/372
https://cocobi.tistory.com/156

0개의 댓글