본문 바로가기
Frontend

[JS] 얕은 복사 & 깊은 복사

by dug_developer 2022. 6. 25.
반응형

자바스크립트에서 값은 원시값과 참조값으로 나뉜다.

원시 값

  • Number
  • String
  • Boolean
  • Null
  • Undefined

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

const a = 1;
let b = a;

b = 2

console.log(a); //1
console.log(b); //2

참조 값

  • Object
  • Symbol
  • 배열

참조값은 변수가 객체의 주소를 가리키는 값이기 때문에 복사된 값(주소)이 같은 값을 가리킨다.

const a = {number: 1};
let b = a;

b.number = 2

console.log(a); // {number: 2}
console.log(b); // {number: 2}

이러한 특징때문에 객체를 복사하는 방법은 2가지로 나뉜다.

얕은 복사 (Shllow Copy)

  • 참조 값을 복사하는 것
  • 계층이 있는 경우에는 제대로 복사가 안됨

방법

1. Object.assign( )

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

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

copyObj.b.c = 3

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

2. spread 연산자

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

const copyObj = {...obj};

copyObj.b.c = 3

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

깊은 복사 Deep Copy

  • 값 내부를 전부 복사하는 것
  • 원본과의 참조가 완전히 끊어짐
  • 다중 배열의 경우에는 spread 연산자와 map메소드를 사용해준다.

방법

1. 재귀 함수

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

2. JSON.stringify( )

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

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

객체를 json 문자열로 변환후 JSON.parse()를 이용해 다시 자바스크립트 객체로 만들어주면 깊은 복사가 된다.

하지만 이 방법은 사용하기는 쉽지만 다른 방법에 비해 아주 느리다고 알려져있다.

3. 라이브러리

lodash 라이브러리

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

const copiedObj = _.cloneDeep(obj);

copiedObj.b.c = 3

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

 

 

REF

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

https://velog.io/@th0566/Javascript-얕은-복사-깊은-복사

반응형

'Frontend' 카테고리의 다른 글

[Front] Virtual DOM  (0) 2022.07.29
리팩터링 총정리  (0) 2022.07.17
웹 표준에 관하여  (0) 2022.06.24
XSS, CSRF  (0) 2022.06.23
sementic tag  (0) 2022.06.21