javascript- 얕은 복사, 깊은 복사

SANGKU OH·2020년 10월 30일
2
post-thumbnail

원시값(Primitive value)

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

  • String
  • Number
  • Boolean
  • Null
  • Undefined
const a = 1;
let b = a;

b = 2

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

참조값(Reference Value)

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

  • Object
  • Simbol
const a = { number: 1 };
let b = a;

b.number = 2

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

위의 특성에 기반해 객체를 복사하는 방법은 크게 두가지로 나뉘게 된다.

얕은 복사(Shallow Copy)

객체를 복사할 때 원래값과 복사된 값이 같은 참조를 가리키고 있는 것
객체 안에 객체가 있을 경우, 한개의 객체라도 원본 객체를 참조하고 있다면 얕은복사라고 한다.

Object.assign()

Object.assign()은 첫번째 요소로 들어온 객체에 다음 인자로 들어온 객체를 복사한다.

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

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

copiedObj.b.c = 3
console.log(copiedObj.b.c) //3
console.log(obj.b.c) //3

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

전개연산자

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

const copiedObj = {...obj}

copiedObj.b.c = 3
console.log(copiedObj.b.c) //3
console.log(obj.b.c) //3

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

깊은 복사(Deep Copy)

깊은 복사된 객체는 객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말한다.

재귀함수를 이용한 복사

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;
}
//함수가 return 하는 것은 obj가 아닌 새로운 객체인 result => 원래값과 복사값이 서로 영향을 받지 않는다.
const copiedObj = copyObj(obj);

copiedObj.b.c = 3
console.log(obj.b.c) //2
console.log(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));
//string(원시값)으로 변환 후 다시 객체로 만들어 주었다. => 원래값과 복사값이 서로 영향을 받지 않는다.

copiedObj.b.c = 3
console.log(obj.b.c) //2
console.log(copiedObj.b.c) //3

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

라이브러리(lodash)

lodash 라이브러리를 사용하면 아~~~주 쉽다.

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

const copiedObj = _.cloneDepp(obj);

copiedObj.b.c = 3;

obj.b.c === copiedObj.b.c //false
profile
Prof.Google을 통해 필요한 정보를 이 곳에 insert 🐸

0개의 댓글