JS의 얕은 복사와 깊은 복사에 대해 알아보자!
복사를 이해하려면 데이터 타입을 이해해야 한다.
data type --|-- PrimitiveType-|-- Number
| |-- BigInt
| |-- String
| |-- Boolean
| |-- null
| |-- undefined
| |-- Symbol
|
|-- Reference Type -- Object - |-- Array
|-- Function
|-- Date
|-- RegExp
|-- Map, WeakMap
|-- Setm WeakSet
위 내용과 같이 데이터 타입은 크게 2가지로 나뉘게 된다.
기본형과 참조형이다.
모든 데이터들은 비트 단위로 저장되고
저장된 데이터들은 바이트 단위의 식별자
좀 더 자세하게 메모리 주솟값을 통해 서로 구분하고 연결할 수 있다.
var a; // 변수 선언
a = 10; // 데이터 할당
var a = 10; // 변수 선언과 할당을 동시에!
주소(변수 영역) | ... | 1002 | 1003 | 1004 | 1005 | ... |
---|---|---|---|---|---|---|
데이터 | 이름: a / 값: @5004 | |||||
주소(데이터 영역) | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 10 |
순서
1. 변수 영역에서 빈공간(@1003)을 확보한다
2. 확보한 공간의 식별자를 a로 지정한다.
3. 데이터영역의 빈 공간(@5004)에 문자열 'abc'를 저장한다.
4. 변수영역에서 a라는 식별자를 검색한다(@1003).
5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.
주소(변수 영역) | ... | 1002 | 1003 | 1004 | 1005 | ... |
---|---|---|---|---|---|---|
데이터 | 이름: a / 값: @5005 | |||||
주소(데이터 영역) | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 'abc' | 'change' |
이렇게 기존의 값은 그대로 있고 새로운 공간에 값을 저장해 할당한다.
기본형 데이터는 모두 값이 변하지 않고 새로 생성해서 변경하기 때문에 불변 값이다.
var obj1 = {
a: 1,
b: 'bbb'
}
주소(변수 영역) | ... | 1002 | 1003 | 1004 | 1005 | ... |
---|---|---|---|---|---|---|
데이터 | 이름: obj1 / 값: @5002 | |||||
주소(데이터 영역) | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | @7103~? | 1 | 'bbb' | |||
주소(객체의 변수 영역) | 7103 | 7104 | 7105 | 7106 | 7107 | ... |
데이터 | 이름: a / 값: @5004 | 이름: b / 값: @5005 |
순서
1. 변수영역의 빈공간 확보 후 주소의 이름을 obj1로 지정
2. 임의의 데이터 저장공간(@5002)에 데이터를 저장하려고 보니 여러개의 프로퍼티로 이뤄진 데이터그룹임
이 그룹의 내부 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고 그 영역의 주소(@7103~?)를 @5002에 저장
3. @7103과 @7104에 각각 a와 b라는 프로퍼티 이름 지정
4. 데이터 영역에서 숫자 1을 검색, 현재 영역에 값이 없음으로 @5004를 할당, b도 동일한 과정을 거침
객체는 데이터 영역의 값이 바뀌지 않지만 할당된 값이 변경 가능하기 때문에 가변형
이러한 데이터의 할당 방식을 가지고 복사를 알아보자.
얕은 복사는 객체를 복사할 때 기존값과 복사된 값이 같은 참조를 가리키고 있는 것을 말한다.
Array.prototype.slice();
Object.assign(생성할 객체, 복사할 객체);
Spread 연산자 (전개 연산자)
깊은 복사는 원본 데이터에 영향을 미치지않게 참조가 끊어진 객체를 말한다.
function deepCopy(object) {
if (object === null || typeof object !== "object") {
return object;
}
// 객체인지 배열인지 판단
const copy = Array.isArray(object) ? [] : {};
for (let key of Object.keys(object)) {
copy[key] = deepCopy(object[key]);
}
return copy;
}
const copy = deepCopy(object);