얕은 복사와 깊은 복사
얕은 복사
얕은 복사는 단순하게 복사할 객체의 껍데기(?) 만 복사한다는 의미이다.
깊은 복사
깊은 복사는 객체의 껍데기는 물론 그 세세한 알맹이까지 전부 복사한다는 의미이다.
그래서 얕은 복사와 깊은 복사가 무엇인데!
자바스크립트에서 배열과 객체는 참조형 데이터이다. 배열과 객체에 담긴 값은 Heap
이라는 저장소에 저장된다. 참조형 데이터가 가지는 값은 오로지 Heap
에 담긴 값의 주소이다. 즉, 배열과 객체를 새로운 변수에 할당하거나, 복사하는 메소드를 사용하는 경우, 배열과 객체의 값이 아닌 Heap
의 주솟값을 복사한다.
결론적으로 원본과 사본이 같은 주소를 가리키게 된다. 만약 사본에서 변경이 발생하는 경우, 원본도 함께 바뀌는 문제가 생기게 된다.
그래서 참조형 데이터는 주솟값이 아닌 그 주소에 담긴 값까지 복사해야 한다.
얕은 복사의 예시는 다음과 같다.
Array.prototype.slice()
메소드spread
연산자를 통한 복사Object.assign()
메소드
깊은 복사의 예시는 다음과 같다.
- 재귀적 방법
JSON.parse
&JSON.stringify
Array.prototype.slice()
slice()
는 배열의 시작부터 끝까지 얕은 복사본을 새로운 배열로 반환한다. 만약 배열의 깊이가 1이라면(중첩 배열이 없다면) 깊은 복사가 수행되지만, 깊이가 2 이상인 경우 깊은 복사가 수행되지 않는다.
let a = [1, 2, [3, 4]];
let b = a.slice();
a[0] = 'a';
b[0] = 'b';
console.log(a); // ['a', 2, [3,4]]
console.log(b); // ['b', 2, [3,4]]
a[2][1] = 'c';
b[2][0] = 'd';
console.log(a); // ['a', 2, ['d', 'c']]
console.log(b); // ['b', 2, ['d', 'c']]
이는 spread
연산자, Array.from()
, concat()
의 결과와 동일하다.
Object.assign()
Object.assign()
은 객체를 복사하는 방법이다. 이는 배열과 마찬가지로 깊이가 1일땐 깊은 복사가 가능하나, 깊이가 2 이상일 땐 깊은 복사가 되지 않는다.