얕은 복사와 깊은 복사

미어캣의 개발일지·2024년 1월 17일
0

📚 얕은 복사와 깊은 복사

코드를 짜다보면 배열이나 객체등을 복사해야하는 상황이 발생한다. 이때 얕은복사깊은복사의 개념을 모르고 있으면 문제가 발생할 수 있다.

간단하게 말하면

얕은복사는 데이터가 저장된 메모리 주소값을 복사
깊은복사새로운 메모리 공간실제값을 복사


📕 얕은 복사(Shallow Clone)

const obj = { a : { b : 1 }}
const objCopy = obj;

objCopy.a.b = 3

console.log(obj.a.b)	// 3
console.log(obj === objCopy)	// true

objCopy의 a.b의 값을 1에서 3으로 변경하였더니
obj의 a.b의 값도 변경 되었다.
그 이유는 objCopy가 obj의 참조값을 복사했기 때문이다.

이는 데이터를 복사한것이 아닌 데이터의 참조값을 전달하여 한 데이터를 공유한다.




📕 깊은 복사(Deep Clone)

let a = 1;
let b = a;

b = 3;

console.log(`a는 ${a} b는 ${b} 이다.`);
// a는 1 b는 3 이다.
console.log(a === b)	// false

b에 a값을 할당하고 b의 값을 변경해도
기존의 a값은 변경되지 않는다.
이는 독립적인 메모리값 자체를 할당하여 생성하는 것 이다.

📕 깊은 복사의 종류

📖 Object.assign()

let obj = {a : 1}
let objCopy = Object.assign({}, obj);

objCopy.a = 3;

console.log(obj)	// {a:1}
console.log(obj === objCopy)	// false

objCopy값을 변경해도 obj의 값이 바뀌지 않는다.

💡 2차원 객체를 복사했을때는 깊은 복사가 이뤄지지 않는다(위 얕은복사 코드 참조)


📖 전개 연산자(Spread Operator)

let obj = {
	a: 1,
  	b: 2,
}

let objCopy = {...obj};

objCopy.b = 3;

console.log(obj.b)	// 2
console.log(obj.b === objCopy.b)	// false

💡 2차원 객체를 복사했을때는 깊은 복사가 이뤄지지 않는다


📖 JSON의 stringify()와 parse()

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

let objCopy = JSON.parse(JSON.stringify(obj));

objCopy.b.c = 3;

console.log(obj.b.c)	// 2
console.log(obj.b.c === objCopy.b.c)	// false
  • stringify(): 객체를 인수로 받으며 받은 객체는 문자열로 치환
  • parse(): 문자열을 인수로 받으며 받은 문자열은 객체로 치환

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


📖 재귀 함수

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

function isCopyObj(obj) {
    let res = {};

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

    return res;
}

let objCopy = isCopyObj(obj);

copy.b.c = 3
console.log(obj.b.c === objCopy.b.c) //false

복사된 objCopy값을 확인해보면 2차원 객체의 값도 깊은 복사가 되었다.

📖 lodash 라이브러리의 cloneDeep()

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

let objCopy = lodash.cloneDeep(obj);

objCopy.b.c = 3;
console.log(obj.b.c); // 3
console.log(obj.b.c === objCopy.b.c);	// false

loneDeep() 메소드를 이용하면 깊은 복사를 간편하게 구현할 수 있다.




📕 참조

https://choiblack.tistory.com/41
https://cocobi.tistory.com/156
https://dori-coding.tistory.com/entry/JavaScript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%ACShallow-Copy%EC%99%80-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%ACDeep-Copy

profile
이게 왜 안되지? 이게 왜 되지?

0개의 댓글