티스토리 뷰

반응형

javascript의 변수를 다른 값으로 복사를 하려고 한다. 이때 우리의 생각처럼 복사가 이루어지지 않는다. 왜냐하면 자바스크립트의 복사 방법은 깊은 복사와 얕은 복사로 나누어 지기 때문이다.

 

 

 

 

보통은 아래와 같이 변수를 만들어서 복사를 한다.

 

let a = '10';
b = a;

 

매우 간단한 예이다. 우리는 b에 10이 담겨 있음을 직관적으로 이해할 수 있다. 여기서 변수란, 값을 저장하기 위한 메모리 공간을 식별하기위해 붙인 이름이다. 즉, 변수 사용 시 자바스크립트 엔진은 변수에 메모리 주소를 기억하게 하여, 변수 사용 시 저장된 메모리 주소로 가서 저장된 값을 가져온다. 이러한 방식은 아래의 타입에 따라 약간씩 다르다.

 

1. Primitive Type (원시 타입)

원시 타입에는 number, string, boolean, null, undefined, symbol(ES6) 이 있다. 이러한 값은 데이터가 생성 및 복사 시 새로운 메모리 공간을 확보하여 독립적인 값들을 저장한다. 따라서 데이터 변경 시 우리는 변경한 것 처럼 보이지만, 실제로는 새로운 메모리에 재할당을 한다. 메모리에 재할당을 하기 때문에 값이 변하지 않는 불변성을 가진다.

 

2. Reference Type (참조 타입)

원시 타입과 같이 메모리에 직접 접근하지 않고, 간접적인 참조를 통해 메모리에 접근을 한다. 예를 들면, 변수에 array를 할당하면 변수에 메모리 주소를 저장한다. 그리고 각각의 Array에 들어 있는 값은 앞에서 저장한 메모리 값에, 다시 다른 메모리 값에 array에 포함된 요소들을 하나씩 저장한다. 디테일한 부분은 아래에서 좀 더 살펴 보자. 참조타입으로는 원시 타입을 제외한 나머지 전부인, Array, Function, Object(전부 객체)이다. 

 

3. 깊은 복사 (deep copy)

원시 타입은 독립적인 메모리에 할당을 한다. 따라서 복사를 하고 수정 시 기존 값은 변하지 않는다. 이를 깊은 복사라 한다.

 

let a = '1';
let b = a;

console.log(a) // '1'
console.log(b) // '1'

b = '2';

console.log(a) // '1'
console.log(b) // '2'

 

위의 예제는 간단하고 직관적으로 이해할 수 있다. a의 값을 b에 할당했으니, a와 b는 같은 값이다. 그리고 b에 '2'를 할당했으니, b는 '2'가 된다. 그러나, b에 할당을 했을 때, a가 변하는 경우가 있다. 즉, 복사나 수정 시, 기존 값이 변하는 것이 바로 얕은 복사이다.

 

4. 얕은 복사 (shallow copy)

객체 복사 시 값 자체를 복사하는 것이 아닌, 힙 메모리 주소값을 복사하는 것이다. 간단히 아래의 예를 보자.

 

let a = [1, 2, 3];
let b = a;

console.log(a); // [1, 2, 3]
console.log(b); // [1, 2, 3]

b[1] = 10000;

console.log(a); // [1, 10000, 3]
console.log(b); // [1, 10000, 3]

 

a를 b에 넣었다. 그런데, b를 변경했는데, a도 동시에 변경이 되었다. 상식적으로 복사한 이유가 사라진다. 같이 변경되면 왜 같이 쓰나!!!! 이러한 해결책은 아래와 같다.

 

 

5. 참조 타입의 깊은 복사

여러가지 방식이 있지만 두 가지 방식을 소개 하려 한다.

 

5.1. json 객체 메소드

문자열로 변경한 후에 다시 파싱하여 객체로 만드는 방식이다.

 

const copyObj = ( obj ) => JSON.parse(JSON.stringify(obj));

let a = [1, 2, 3];
let b = copyObj(a);

b[1] = 1000;

console.log(a); // [1, 2, 3];
console.log(b); // [1, 1000, 3];

 

 

5.1. Lodash의 deepclone

라이브러리를 이용하는 방식으로 아래와 같이 사용하면 된다.

 

const _ = require("lodash");

let a = [1, 2, 3];
let b = _.cloneDeep(a);

b[1] = 1000;

console.log(a); // [1, 2, 3];
console.log(b); // [1, 1000, 3];
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함