[JavaScript] 깊은 복사 (Deep Copy) 하는 방법

Donghwa Kim·2022년 11월 29일
0

JavaScript 동작원리

목록 보기
4/7

본 글은 정재남 님의 저서 <코어 자바스크립트>를 읽고 정리한 내용입니다.

들어가기 전에

이전 포스팅에서 객체를 복사하는 몇 가지 방법에 대해 알아보았다. 하지만 이 방법들은 객체의 깊이1인 경우 (중첩 객체가 아닌 경우)에만 깊은 복사가 된다. 그렇기 때문에 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때는 그 주소값이 저장되므로 결과적으로 얕은 복사가 되는 셈이다.

이번 포스팅에서는 중첩 객체deep copy 하는 두 가지 방법을 알아보려고 한다.

방법1: 재귀적 호출

첫 번째 방법은 재귀적 호출을 이용한 방법이다.

var copyObjectDeep = function (target) {
  var result = {};

  // null의 type도 object이기 때문에 target !== null 조건 추가
  if (typeof target === 'object' && target !== null) {
    for (var prop in target) {
      result[prop] = copyObjectDeep(target[prop]);
    }
  } else {
    result = target;
  }

  return result;
}
  • 위 방법은 target객체인 경우에 내부 프로퍼티들을 순회하면서 copyObjectDeep 함수를 재귀적으로 호출한다.

  • 객체가 아닌 경우에는 target을 그대로 지정한다.

이 함수를 사용해 객체를 복사한 후에는 원본사본전혀 다른 객체참조하게 된다. 이제는 어느 쪽의 프로퍼티를 저장하더라도 서로에게 영향을 주지 않는다.

단, 위 코드의 경우 프로퍼티가 배열인 경우 객체로 변환되어 복사되므로 수정이 필요하다.

getter와 setter도 복사되지 않는다.

방법2: JSON 활용

재귀 호출보다 더 간단한 방법이 있다. 바로 JSON을 활용한 방법이다.

원리는 객체를 JSON문법으로 표현된 문자열로 전환했다가 다시 JSON객체로 바꾸는 것이다. 이 방법은 단순하지만 아주 잘 작동한다. 다만 메서드(함수)나 숨겨진 프로퍼티인 __proto__getter/setter등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시한다.

httpRequest로 받은 데이터를 저장한 객체를 복사할 때 유용할 수 있다.

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

let obj = {
  a: 1,
  b: {
    c:1,
    d:2,
  }
}

let newObj = copyObjectViaJSON(obj);

newObj.b.c = 100;

console.log(obj); // { a: 1, b: { c: 1, d: 2 } }
console.log(newObj); // { a: 1, b: { c: 100, d: 2 } }

방법3: Lodash 라이브러리 사용

Node.js에서 Lodash를 사용하려면 우선 Pacakge를 다운로드 받아야 한다.

  • npm i lodash
const lodash = require('lodash');

const object = {
  a: "a",
  number: {
    one: 1,
    two: 2,
  },
  arr: [1, 2, [3, 4]],
};

const object2 = lodash.cloneDeep(object);

object.number.one = 1000;
object.number.two = 2000;

console.log(object); // { a: 'a', number: { one: 1000, two: 2000 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(object2); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }

References

profile
Slow but steady wins the race🏃‍♂️

0개의 댓글