프로그래밍/JavaScript

[JS] 얕은 복사, 깊은 복사 차이 쉽게 이해하기

choar 2022. 3. 31. 20:27
반응형

[JS] 얕은 복사, 깊은 복사 차이 쉽게 이해하기

 

자바스크립트의 얕은 복사(shallow copy), 깊은 복사(deep copy)에 대해 쉽게 이해해보자.

이에 대해 이해하려면 먼저 자바스크립트의 원시 타입(primitive type)과 객체 타입(object/reference type)에 대해 이해해야 한다.

자바스크립트에서 데이터 타입은 크게 원시 타입과 객체 타입으로 나뉜다.

원시 타입에는 Number, BigInt, String, Boolean, Null, Undefined, Symbol 7개의 타입이 있고,

그 외 모든 데이터는 객체 타입이다.

 

원시 값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장된다.

반면에, 객체를 변수에 할당하면 변수(확보된 메모리 공간)에는 참조 값(메모리 주소)이 저장된다.

이를 코드와 그림으로 나타내면 다음과 같다.

(左) 원시 값의 변수 할당 (右) 객체의 변수 할당

객체는 참조 값을 복사하기 때문에 let obj2 = obj1와 같이 객체를 복사할 경우 얕은 복사가 일어난다.

얕은 복사(shallow copy)는 원본 객체는 하나인 상태에서, 참조 값만 복사한다.

깊은 복사(deep copy)는 원시 값처럼 완전한 복사본을 만든다. 깊은 복사는 lodash의 cloneDeep을 사용해 수행 가능하다.

 

얕은 복사, 깊은 복사

 

let obj1 = { name: 'choar', age: 20 };
let obj2 = obj1;
console.log(obj1); // { name: 'choar', age: 20 }
console.log(obj2); // { name: 'choar', age: 20 }

obj1.name = 'hi';
console.log(obj1); // { name: 'hi', age: 20 }
console.log(obj2); // { name: 'hi', age: 20 }
// 얕은 복사로 인해 obj1, obj2가 가리키는 객체는 같다.

// lodash의 cloneDeep을 사용한 깊은 복사
// "npm install lodash"로 lodash를 설치한 후, Node.js 환경에서 실행
const _ = require('lodash');
let obj3 = _.cloneDeep(obj1);
obj3.name = 'hello';
console.log(obj1); // { name: 'hi', age: 20 }
console.log(obj3); // { name: 'hello', age: 20 }

추가로, 객체의 경우 변수가 참조 값을 저장하고 있기 때문에 const로 선언해도 내부 프로퍼티 값 변경이 가능한 것이다. (참조 값은 변경 불가, 참조 값이 가리키는 객체는 변경 가능)

 


References

모던 자바스크립트 Deep Dive (Chapter 11)

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures

반응형