[JavaScript] 깊은복사, 얕은복사

DY·2022년 8월 21일
0

JavaScript

목록 보기
10/12

JavaScript에서 객체를 공부하다 객체를 복사할 때 의문이 생겼다. 객체를 복사한 후 복사한 객체를 수정했더니 원본 객체의 값이 변했다 왜그럴까?

let a = {name : "K"}
let b = a;
b.name = "D";

console.log(a.name) // D
console.log(a===b) // true;

대입연산으로 객체를 변수에 할당하면 원래 객체의 주소값이 할당 됨을 확인 할수 있었다.

이것을 얕은 복사라고 말하고 '참조에 의한 객체 복사'라고도 말한다.


얕은 복사가 아닌 서로 다른 객체를 만들고 싶다면 깊은 복사를 하면 된다.

  1. 객체의 모든 프로퍼티를 순회하면서 복제할 객체에 추가

    for (let key in obj) {
    clone[key] = obj[key];
    }

  2. Object.assign 함수 사용

    Object.assign(clone, [obj1, obj2, obj3...])
    obj1 ~ 3 의 프로퍼티들을 clone객체에 추가

    • 기존 객체에 복제할 프로퍼티가 이미 존재한다면 값이 변경됨
  1. slice 함수 사용

  2. spread operator (전개 연산자) 사용

    let clone = {...obj}

위의 4가지 방법은 depth가 1일 때만 가능하다. 즉 객체안에 객체가 선언이 되어있거나 2차원배열 이상이라면 해당 프로퍼티는 깊은 복사가 아닌 얕은 복사가 된다.

  • 배열의 실제 값들은 힙에 저장이 된다. 이때 depth가2인 [1,2,3 [4,5]]로 구성된 배열은 [1,2,3,주소값] 이렇게 힙에 저장되어있기 때문에 depth가2인 배열을 복사한다면 [1,2,3,주소값]을 복사하는것과 같다.

깊은복사

  1. 재귀적으로 해결
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;
}

let obj  = {
  name: "k",
  subobj : {
    age : "10"
  }
};

let clone = cloneObject(obj);

console.log(obj);
console.log(clone);

console.log(obj===clone); //false
console.log(obj.subobj === clone.subobj); //flase
  1. lodash 라이브러리 사용
let clone = _.cloneDeep(obj);

정리

얕은 복사 : 객체를 새로운 변수에 할당 했을 때 객체의 값들이 복사가 되는게 아닌 객체의 주소값이 할당이 되는 복사. 따라서 복사한 변수의 값을 바꾸면 원래 객체의 값도 바뀐다. 참조에 의한 객체 복사라고도 한다.
깊은 복사 : 얕은 복사와 달리 주소값이아닌 값 자체를 복사하는 것.

profile
프론트엔드 개발자가 되기 위해 공부중입니다. 블로그는 공부한 내용을 올리고 있습니다.

0개의 댓글