얕은 복사 깊은 복사

»

얕은 복사 깊은 복사

얕은 복사

원시값은 값을 복사할 때 복사된 값을 다른 메모리에 할당하기 때문에 원본과 복사본이 서로에게 영향을 미치지 않는다

const a = 1;
let b = a; // b에 a를 할당

b = 2; // b값을 바꿔줌

console.log(a); // 1 => a값은 바뀌지 않았음
console.log(b); // 2

즉 얕은 복사 ⇒ 레퍼런스(주소) 안의 요소들이 값으로 복사는 됐는데, 레퍼런스 안에 레퍼런스가 있다면 복사가 안되고 주소로 됨

Object.assign()

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

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

const objCopy = Object.assign({}, obj);
objCopy.b.c = 3; // 복사한 objCopy.b.c에 3으로 변경

obj === objCopy // false => 원본과 복사본은 다름
obj.b.c === objCopy.b.c // true => 그러나 깊게 복사가 되지않아 c의 값은 같음

전개연산자

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

const objCopy = {...obj}; // spread로 복사

objCopy.b.c = 6; // c를 6으로 변경

obj === objCopy // false => 복사본과 원본은 다름
obj.b.c === objCopy.b.c // true => 하지만 깊게보면 원본에 c값도 바껴있음

깊은 복사

깊은 복사 ⇒ 다 새로운 것으로 복사가 됨

재귀함수를 이용한 복사

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

function copyObj(obj) {
  const result = {};

  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      result[key] = copyObj(obj[key]);
    } else {
      result[key] = obj[key];
    }
  }

  return result;
}

const copiedObj = copyObj(obj);

copiedObj.b.c = 3

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

JSON.stringify()

JSON.stringify() **는 객체를 json 문자열로 전환하는데 이과정에서 원본 객체와의 참조가 모두 끊어지게됩니다

객체를 json 문자열로 변환후 JSON.parse() 를 이용해 다시 객체로 만들어주면 깊은 복사가됩니다

사용은 쉬우나 다른 방법에 비해 느립니다

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

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

copiedObj.b.c = 3

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

라이브러리 사용

lodash 라이브러리를 사용하면 깊은 복사를 더 쉽게 할 수 있습니다

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

const copiedObj = _.cloneDeep(obj);

copiedObj.b.c = 3

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