얕은 복사 (shallow copy) 와 깊은 복사 (deep copy)
얕은 복사와 깊은 복사는 참조형에만 해당된다.
얕은 복사
javascript의 참조형은 가변성 때문에, 데이터를 복사해오는 것에 주의가 필요하다. 이때 얕은 복사는 참조형 데이터의 1차원 데이터만 복사한다. 더 깊은 차원의 데이터는 깊은 복사를 이용해서 가져온다.
얕은 복사는 객체의 경우 Object.assign()을 통해, 배열의 경우 concat()을 통해 할 수 있으며, 두 가지 데이터 모두 공통적으로 스프레드 연산자 ... 을 사용할 수 있다.
// 얕은 복사(shallow copy) - 참조형의 1차원 데이터만 복사
let a = 1
let b = a
// a 주소의 메모리 주소가 b에 할당됨
b = 2
console.log(b);
console.log(a);
b = 3
console.log(b);
console.log(a);
// 원시형 데이터는 b변수에 a변수 메모리 주소를 할당하더라도, b변수의 수정이 a변수에 영향을 주지 않는다.
// -> 원시형은 같은 모양이면 같은 메모리에 할당됨
// 참조형 데이터의 가변성
// const a1 = {x:1};
// const b1 = a1;
// b1.x = 2;
// console.log(a1); // {x:2}
// console.log(b1); // {x:2}
// 얕은 복사
const a1 = {x:1};
const b1 = Object.assign({}, a1); // 새로운 객체 생성
const b1_1 = {...a1}; // 전개연산자 사용
b1.x = 2;
console.log(a1); // {x:1}
console.log(b1); // {x:2}
// 참조형 데이터 안에 또 참조형 데이터가 있다면, 얕은 복사만으로는 수정을 막을 수 없다.
const a2 = {x:{y:1}};
const b2 = {...a2};
b.x.y = 2;
console.log(b2); // x:{y:2}
console.log(a2); // x:{y:2}
깊은 복사
얕은 복사는 1차원 데이터만 복사해올 수 있다. 즉, 객체 안에 객체가 있거나 배열 안에 배열이 있는 경우를 온전히 복사해오지는 못한다. 이럴 경우에는 모든 차원의 데이터를 복사할 수 있는 깊은 복사를 사용 해야 한다. 깊은 복사를 할 수 있는 방법은 크게 3가지가 있다.
1. JSON.parse(), JSON.stringify()를 이용한다. 이 경우, JSON 문자로 변환되는 과정에서 참조가 끊긴다. 하지만 속도가 느리다는 단점이 있다. 또, function은 undefined를 반환한다.
2. 재귀함수를 구현한다. 단점으로는 구현하기가 복잡하다.
3. lodash 라이브러리를 이용한다. 간편하지만, 코딩테스트에서 사용할 수 없다는 게 단점이다.
// 깊은 복사(deep copy) - 참조형의 모든 차원 데이터를 복사, 복사된 두 객체는 완전히 독립적인 메모리를 차지
//객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊긴 객체를 이른다.
// 구현하기 쉽지 않다.
// 1. JSON.parse(), JSON.stringify()를 이용한다. json 문자열로 변환하는 과정에서 원본 객체와의 참조가
// 모두 끊어지기 때문이다. 가장 간단하지만, 느리고 function일 경우에는 undefined로 처리된다.
// 2. 재귀함수를 구현해서 복사한다. 쉽지 않다. 복잡하다.
// 3. lodash library를 이용한다.
import { cloneDeep } from "lodash";
const a2_1 = {x:{y:1}};
const b2_1 = cloneDeep(a2);
b2_1.x.y = 2;
console.log(a2_1); // x:{y:1}
console.log(b2_1); // x:{y:2}
'JAVASCRIPT' 카테고리의 다른 글
[JavaScript] 쓰레기 수집 (Garbage Collection) (0) | 2023.04.27 |
---|---|
[JavaScript] 메모리 누수 (Memory Leak) (0) | 2023.04.27 |
[JavaScript] 불변성과 가변성 (0) | 2023.04.27 |
[JavaScript] 이벤트 - Focus & Form Event (0) | 2023.04.24 |
[JavaScript] 이벤트 - Keyboard Event (0) | 2023.04.24 |