[JS]얕은 복사, 깊은 복사

Kng_db·2022년 12월 15일

이번 Todolist를 만들며 배열, 객체에 대한 복사가 어떻게 이루어지는지 의문이 들었고
거기에 대해 알아봤다.

const A = [...todos] // todos = 객체로 이루어진 배열

이런 형태였는데 내 생각으론 todos가 원래 객체로 이루어진 배열인데 const A에 복사하는 과정에서 다시 배열로 감싸줘야하나 라고 생각했고,
전개 구문에 의해 배열에서 나와 하나 하나 값을 가지니 다시 배열화 해준 거라고 생각했다.

=> 구조분해할당이 아닌가??

저렇게 하는 이유는 todos에 영향을 주지 않으면서 그 안의 값들을 사용하기 위해 A로 복사하는 거라고 생각했다. 좀 더 자세히 알아보자.

얕은 복사, 깊은 복사

js에서 얕은 복사와 깊은 복사를 이해하기 위해서는 js의 원시 타입과 객체 타입을 이해해야한다.

  • 원시 타입
    1.Number // 1, 2, 3, 4...
    2.BigInt // BigImt MDN
    3.String // 문자열
    4.Boolean // true, false
    5.Null // 비어있음을 표현하며 불리언 연산에서는 거짓으로 취급
    6.Undefined // undefined 원시 값 헷갈리면 Undefined MDN
    7.Symbol // 익명의 객체 속성을 만들 수 있는 특성을 가진 원시 데이터 형식 Symbol MDN
  • 객체 타입 = 원시 타입 이외의 모든 데이터

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

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

얕은 복사

얕은 복사는 객체를 직접 대입해 참조에 의한 할당(두 개의 식별자가 하나의 객체를 공유)이 이루어져 같은 데이터(주소)를 갖는다.
원본과 사본 어느 한 쪽에서 객체를 변경하면 서로 영향을 준다.

const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true
_________________________________________

const obj1 = { a:1, b:2 };
const obj2 = obj1;
obj2.a = 100;
console.log( obj1.a ); // 100

깊은 복사

깊은 복사는 원시 값처럼 완전한 복사본을 만든다. 깊은 복사는 lodash의 cloneDeep을 사용해 수행 가능하다.
하지만 아래처럼 깊은 복사도 가능하다. (1 depth 까지만)

// Spread 문법은 배열을 복사할 때 1 레벨(1 depth) 깊이에서 효과적으로 동작한다.
const obj1 = { a:1, b:2 };
const obj2 = { ...obj };
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1


깊은 복사는 원래 안의 값을 완벽히(deep) 복사해서 사용하는 거라고 한다.
위의 예시들은 깊은 복사 중에서도 가벼운(?) 깊은 복사라고 한다.
아직은 1depth 이상 사용하질 않아서 더 깊은 복사가 필요한가 싶지만 나중에 시간이 되면 한 번 더 알아봐야겠다.

profile
코딩 즐기는 사람

0개의 댓글