JavaScript | 얕은 복사와 깊은 복사

Kate Jung·2022년 8월 4일
0

JavaScript

목록 보기
37/39
post-thumbnail

📌 얕은 복사 (shallow copy)

바로 아래 단계의 값만 복사

🔹 원리 & 문제점

중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사

그러면 해당 프로퍼티에 대해 원본과 사본이 모두 동일한 참조형 데이터의 주소를 가리키게 됨. (사본을 바꾸면 원본도 바뀌고 원본을 바꾸면 사본도 바뀜.)

  • 예시 코드

    var copyObject = function (target){
     var result = {};
     for( var prop in target){
       result[prop] = target[prop];
     }
     return result;
    };
    
    var user = {
     name : 'msk',
     information : {
       friend : '쿠로코',
       school : '토키와다이'
     }
    }
    
    var user2 = copyObject(user);
    
    user2.name = 'kim';
    console.log(user.name === user2.name); // false
    
    user.information.school = '단국대학교'
    console.log(user.information.school === user2.information.school) //true

🔹 데이터 타입별 비교

객체 내부의 모든 값을 복사하려는 경우

  • 기본형 데이터인 경우

    그대로 복사

  • 참조형 데이터인 경우

    다시 그 내부의 프로퍼티들을 복사해야 함.

    → 재귀적으로 수행해야만 깊은 복사 가능

🔹 방법

✦ Object.assign()

첫번째 요소로 들어온 객체에 다음인자로 들어온 객체를 복사

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = Object.assign({}, obj);

copiedObj.b.c = 3

obj === copiedObj // false
obj.b.c === copiedObj.b.c // true

✦ Spread Operator

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = {...obj}

copiedObj.b.c = 3

obj === copiedObj // false
obj.b.c === copiedObj.b.c // true

📌 깊은 복사 (deep copy)

내부의 모든 값들을 하나하나 찾아서 전부 복사

🔹 방법

✦ 재귀 함수

var copyObjectDeep = function (target){
  var result = {};
  if(typeof target === 'object' && target !== null){
  	for( var prop in target){
    	result[prop] = copyObjectDeep(target[prop]);
  	}
  }
  else{
  	result = target
  }
  return result;
};

재귀로 내부가 객체라면 내용을 반복해서 복사

✦ hasOwnProperty

프로토타입 체이닝을 통해 상속된 프로퍼티 복사 x

  • ES5의 getter/setter 복사 방법

    ES6의 Object.getOwnPropertyDescriptor 또는 ES2017의 Object.getOwnPropertyDescriptors외 마땅한 방법 無

✦ JSON

  • 원리

    객체를 JSON문법으로 표현된 문자열로 전환 → JSON 객체로 전환

  • 활용하기 좋은 경우

    순수한 정보만 다룰 때

    ex. httpRequest로 받은 데이터를 저장한 객체를 복사할 때

  • 단점

    • 무시하는 경우

      • 메서드(함수)
      • 숨겨진 프로퍼티 (__proto__)
      • JSON으로 변경 불가한 프로퍼티들 (getter/setter)
    • 아주 느리다고 알려짐 (다른 방법에 비해)

  • 예시 코드

    var copyObjectViaJson = function (target){
      return JSON.parse(JSON.stringify(target));
    }

✦ 라이브러리(lodash) 함수

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = _.cloneDeep(obj);

copiedObj.b.c = 3

obj.b.c === copiedObj.b.c //false

참고

profile
복습 목적 블로그 입니다.

0개의 댓글