깊은 복사, 얕은 복사

Vorhandenheit ·2021년 7월 26일
0

JS/Node 

목록 보기
9/63

깊은 복사, 얕은 복사

1. 얕은 복사

사본을 만들어내지않고 원본을 참조하도록 복사한 척을 하는 것

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

obj2에 값을 바꿨는데도 불구하고 obj1의 값도 바뀐 걸 확인할 수 있다.
obj2가 obj1과 같은 곳을 참조하고 있기 떄문이다

2.깊은 복사

완벽하게 원본과 사본을 나눠 복사하는 방법

1.Object.assign()

const obj = {a : 1},
const newObj = Object.assign({}, obj)
newObj.a = 2;
console.log(obj); // {a : 1}
console.loog(obj === newObj); false

하지만 object.assign()의 경우 depth 1을 넘어갈 떄 깊은 복사가 이루어지지 않음

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(obj2.b.c === newObj.b.c) // true

전개연산자(...)도 Object.assign()와 마찬가지로 객체의 복사가 가능하지만 depth1을 넘어갈 때 얕은 복사가 된다

2.JSON 객체 메소드 이용

  • 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}
}

메소드를 이용하여 문자열로 변환한 뒤 다시 객체로 변환시키는 방법

문제점

(1)

const obj = {d : new Date()};
const copied = JSON.parse(JSON.stringify(obj));
checker(obj, copied); //false


같은 날짜 시간을 가리키는 데이터라고해도 보여지는 방식이 다르기 떄문에 다른 값으로 간주

(2)JSON 은 ECMA-404헤 해당하는 값 (object, array, number, string, true, false, null) 이 7개만 값으로 인정함
그래서 SON.stringfy() 메소드는 함수를 만났을 떄 undefined로 처리함

(3) 과정을 두번거치기 떄문에 다른 방법에 비해 느리다!

3. Lodash

Lodash의 cloneDeep() 사용

const original = {a: {b: 2}};
let copy = _.cloneDeep(original);
copy.a.b = 100;
console.log(original.a.b); //2

4. 커스텀 재귀 함수 사용

직접 깊은 복사를 실현하는 함수를 만드는 것

function cloneObject(obj) {
  var clone = {};
  for (var key in obj) {
    if (typeof obj[key] == "object" && obj[key] != null) {
      clone[key] = cloneObject(obj[key]);
    } else {
      clone[key] = obj[key];
    }
  }

  return clone;
}
profile
읽고 기록하고 고민하고 사용하고 개발하자!

0개의 댓글