[JS] 얕은 복사 Shallow copy 와 깊은 복사 Deep copy

소연·2023년 11월 4일
2

일러두기

  • 본 글은 모던 자바스크립트 Deep Dive 11절, ‘원시값과 객체의 비교’ 챕터를 읽고 이해한대로 작성한 글입니다. 글에 틀린 부분이 있다면 언제든지 댓글로 남겨주세요.
  • 모던 자바스크립트 공식 github의 예시코드를 사용했습니다

목차

  • 용어
  • 값에 의한 전달, 참조에 의한 전달
  • 얕은 복사와 깊은 복사의 두 가지 의미

용어

  • 변수
    하나의 값을 저장하기 위해 확보한 메모리 공간 자체, 또는 그 메모리 공간을 식별하기 위해 붙인 이름

  • 변수에 저장된 데이터
  • 원시 타입 primitive type
    이 변경 불가능한, immutable 한 값
  • 객체 타입 reference/object type
    이 변경 가능한, mutuable 한 값

값에 의한 전달 (call by value), 참조에 의한 전달 (call by reference)

let score = 80;
let person = {name: ahn};

primitive 타입과 reference 타입의 자료형은 처음 선언할 때부터 차이가 드러난다.

primitive 타입 중 하나인 숫자형 80을 score라는 변수에 저장할 땐 80이라는 수 자체가 메모리에 할당된다.

하지만 객체를 만들어 person이라는 변수에 할당하고자 했을 때 person에 할당 된 것은 객체 자체가 아닌, 객체에 접근할 수 있는 주소값인 모습이다.

이 상태에서 각 변수 score, person을 각각 copy라는 새로운 변수에 할당해보자.

let copy = score;
let copy = person;

이 순간 일어나는 것은 엄밀히 말하자면 두 경우 모두 ‘값에 의한 복사 pass by value’이다. 용어 목차에서 정리했듯이, 값이란 변수에 저장된 데이터이기 때문이다. 왼쪽 경우에는 80이라는 값이 복사 되었고, 오른쪽 경우에는 0x00001332 라는 값이 복사된 것 뿐이다. 이를 두고 저자는 “자바스크립트에는 ‘참조에 의한 전달’은 존재하지 않고 ‘값에 의한 전달’만이 존재한다고 말할수 있다”고 서술해두었다. 새로운 변수에 값을 할당시 할당되는 값이 원시형 primitive type이냐, 참조형 reference tyepe이냐에 따라 두 방식을 구분지어 말하기 위한 용어이다.

얕은 복사와 깊은 복사의 두 가지 의미

  • ‘모던 자바스크립트 딥다이브’ 에서 저자는 얕은 복사와 깊은 복사 개념을 설명하는 두 가지 서로 다른 방식을 언급한다.
  • 두 가지 얕은 복사와 깊은 복사
    1. 객체를 복사함에 있어서 그 깊이의 차이를 나타낼 때 쓰는 용어로서의 얕은/깊은 복사

      얕은 복사와 깊은 복사 모두 참조값이 원본과 다른 객체를 생성한다. 하지만 다른 점이 있다면 얕은 복사를 사용한 경우 객체 내부의 객체는 원본 참조값을 복사해오고, 깊은 복사는 객체 내부의 객체까지도 모두 원본 참조값과는 다른 객체로 복사해온다는 것이다.

      const o = { x: { y: 1 } };
      
      // 얕은 복사
      const c1 = { ...o }; // 35장 "스프레드 문법" 참고
      console.log(c1 === o); // false
      console.log(c1.x === o.x); // true
      
      // lodash의 cloneDeep을 사용한 깊은 복사
      // "npm install lodash"로 lodash를 설치한 후, Node.js 환경에서 실행
      const _ = require('lodash');
      // 깊은 복사
      const c2 = _.cloneDeep(o);
      console.log(c2 === o); // false
      console.log(c2.x === o.x); // false
    2. (위에서 약속한 뜻을 가진) 참조에 의한 복사 pass by reference, 값에 의한 복사 pass by value를 표현하는 또 다른 용어로서의 얕은/깊은 복사

      const v = 1;
      
      // "깊은 복사"라고 부르기도 한다.
      const c1 = v; // pass by value
      console.log(c1 === v); // true
      
      const o = { x: 1 };
      
      // "얕은 복사"라고 부르기도 한다.
      const c2 = o; // pass by reference
      console.log(c2 === o); // true
profile
배우고 정리해요

0개의 댓글