Javascript Object Copy

황상진·2022년 8월 17일
0

JavaScript

목록 보기
26/27

Object Copy

  • shallow copy
  • deep copy

Shallow copy

  • 얖은 복사는 참조(주소)값의 복사를 나타낸다.
const obj1 = {value : 1};
const obj2 = obj1;

obj2.value = 2;
console.log(obj1.value) // 2
console.log(obj1===obj2) // true
  • obj1 객체를 obj2 객체에 할당하였으며 이를 참조 할당이라 부른다.
  • 복사 후 obj2 객체의 value값을 변경하였더니 obj1.value값도 같이 변경된 것을 알 수 있다.
  • 두 객체를 비교해도 true로 나온다.
  • 데이터가 그대로 생성되는 것이 아닌 해당 데이터의 참조 값(메모리 주소)를 전달하여 결국 한 데이터를 공유하는 것이다.

Deep copy

  • javascript 원시타입의 경우 Deep copy가 된다. 메모리에 값 자체를 생성
  • javascript 참조타입의 경우 Deep Copy가 되지 않는다. 메모리 주소(참조값)을 전달하여 하나의 데이터를 공유하기 때문

원시값과 참조값

  • 원시값 - Number, String, Boolean, Null, Undefined, Biglnt, Symbol
  • 참조값 - Object, Array, Function

Deep copy 방법

  • Object.assign()
  • 전개 연산자(Spread Operator)
  • JSON 객체 메소드를 이용
  • 커스텀 재귀 함수
  • lodash 모듈의 cloneDeep()

Object.assign()

  • Object.assign(생성할 객체, 복사할 객체) 메서드의 첫번째 인수로 빈 객체를 넣어주며, 두번째 인수로 할당할 객체를 넣으면 된다.
const obj = { a: 1 };
const newObj = Object.assign({}, obj);

newObj.a = 2;

console.log(obj); // { a: 1 }
console.log(obj === newObj); // false
  • 하지만 Object.assign()를 활용한 복사는 완벽한 깊은 복사가 아니다.
const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

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

newObj.b.c = 3;

console.log(obj); // { a: 1, b: { c: 3 } }
console.log(obj.b.c === newObj.b.c); // true

전개 연산자(Spread Operator)

  • 전개 연산자 사용해서 복사 가능
  • 완전한 깊은 복사는 불가능하다
const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const newObj = { ...obj };

newObj.b.c = 3;

console.log(obj); // { a: 1, b: { c: 3 } }
console.log(obj.b.c === newObj.b.c); // true

JSON 객체 메소드를 이용

  • 객체의 깊은 복사를 위해 JSON 객체의 stringify(), parse() 메소드를 사용할 수 있다.

  • JSON.stringify() 메소드는 인수로 객체를 받으며 받은 객체는 문자열로 치환되며,

  • JSON.parse() 메소드는 문자열을 인수로 받으며, 받은 문자열을 객체로 치환한다.

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

const newObj = JSON.parse(JSON.stringify(obj));

newObj.b.c = 3;

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

문제점

  • 성능이 다른 방법에 비해 느리다
  • JSON.stringify() 메소드는 함수를 만났을 때 undefined로 처리한다는 점

커스텀 재귀 함수

function deepCopy(obj){
	if(obj===null || typeof(obj)!=="object"){
    	return obj;
    }
  
  	let copy ={};
  
  	for (let key in obj) {
      if(obj.hasOwnProperty(key)){
      	copy[key] = deepCopy(obj[key]);
      }
    }
    return copy;
}

lodash 모듈의 cloneDeep()

  • lodash 모듈의 cloneDeep() 메소드를 이용하여 객체의 깊은 복사가 가능하다. 해당 모듈을 설치해 준 뒤 아래 코드를 실행시켜 보자.
const lodash = require("lodash");

const obj = {
  a: 1,
  b: {
    c: 2,
  },
  func: function () {
    return this.a;
  },
};

const newObj = lodash.cloneDeep(obj);

newObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 }, func: [Function: func] }
console.log(obj.b.c === newObj.b.c); // false
profile
Web FrontEnd Developer

0개의 댓글