Javascript에서의 깊은 복사와 얕은 복사 (Javascript)

Devinix·2023년 11월 23일
0
post-thumbnail

이 글에서는 자바스크립트에서의 깊은 복사와 얕은 복사의 개념을 소개하고, 각각의 복사 방법이 언제 어떻게 사용되는지를 예제 코드와 함께 설명한다. 또한, 객체타입에서의 깊은 복사 방법에 대해서도 설명해 보겠다.

원시 타입과 객체타입의 차이에 대한 이해가 없다면, 아래의 내용을 먼저 참고하는것이 본 내용을 이해하는 데 도움이 될 것이다.

https://velog.io/@dpldpl/Javascript-%EC%9B%90%EC%8B%9C-%ED%83%80%EC%9E%85%EA%B3%BC-%EA%B0%9D%EC%B2%B4%ED%83%80%EC%9E%85-Javascript

깊은 복사

깊은 복사(deep copy)
객체의 모든 레벨에서 새로운 복사본을 생성하는 과정이다. 원시 타입의 경우, 기본적으로 깊은 복사가 수행된다. 이는 원시 타입이 불변하고 그 값이 직접 저장되기 때문이다.

// 원시 타입에서의 복사는 항상 깊은 복사이다.
let a = 10;
let b = a;  // 깊은 복사
b = 20;

console.log(a); // 10
console.log(b); // 20

console.log(a === b); // false

// let b = a;는 a의 값(10)만을 b에 저장하는 과정이다.  

얕은 복사

얕은 복사(shallow copy)
객체의 최상위 레벨에서만 새로운 복사본을 생성하고, 내부 객체 또는 값들은 참조를 공유한다. 객체 타입은 기본적으로 얕은 복사가 이루어진다.

// 객체 타입에서의 복사는 기본적으로 얕은 복사이다.
let obj1 = { x: 10, y: 20 };
let obj2 = obj1;  // 얕은 복사

obj2.y = 30;

console.log(obj1); // { x: 10, y: 30 }
console.log(obj2); // { x: 10, y: 30 }

console.log(obj1 === obj2); // true

/* let obj2 = obj1;은 obj1의 값만을 obj2에 저장하는 것이 아니라, 
   obj1 자체가 obj2 완벽하게 같아지게 된다. (같은 메모리 주소를 참조하기 때문) */

객체 타입에서 깊은 복사하는 법

별 다른 설정을 해주지 않는 이상 원시타입에서는 깊은 복사를, 객체 타입에서는 얕은 복사를 수행한다는 것을 알게 되었다. 그렇다면 객체타입에서 어떻게 하면 깊은 복사를 할 수 있을까?

스프레드 연산자를 이용한 방법

객체의 프로퍼티가 전부 원시 타입으로 이루어져 있다면 스프레드 연산자(...)를 이용하여 간단하게 객체를 깊은 복사할 수 있다. 하지만, 스프레드 연산자는 객체의 첫 번째 레벨만 깊은 복사한다는 점에 유의해야 한다. 여기서 첫 번째 레벨이라는 것은, 객체에서의 프로퍼티 중 객체타입을 제외한 모든 원시 타입의 프로퍼티를 의미하는 것이다.

let originalObject = { a: 1, b: 2, c: 3 };
let shallowCopy = { ...originalObject };

console.log(originalObject); // { a: 1, b: 2, c: 3 }
console.log(shallowCopy); // { a: 1, b: 2, c: 3 }

console.log(originalObject === shallowCopy); // false

lodash를 이용한 방법

객체의 프로퍼티 중 참조 타입이 하나라도 있을 때, 스프레드 연산자를 사용한 복사는 참조 타입을 제외한 원시타입만 깊은 복사하게 된다. 그렇다면 이런 상황에서는 어떻게 깊은 복사를 할 수 있을까?

이런 상황에서는 lodash 라이브러리가 적절한 해결책이 될 수 있다. lodash는 객체의 깊은 복사를 쉽게 구현할 수 있는 _.cloneDeep() 함수를 제공하는데, 이 함수는 객체의 모든 레벨에서 새로운 복사본을 생성한다.

import _ from 'lodash';

let obj1 = { x: 10, y: { z: 20 } };
let obj2 = _.cloneDeep(obj1);  // lodash를 이용한 깊은 복사

obj2.y.z = 30;

console.log(obj1); // { x: 10, y: { z: 20 } }
console.log(obj2); // { x: 10, y: { z: 30 } }

console.log(obj1 === obj2); // false
profile
프론트엔드 개발

0개의 댓글