Reference type 복사의 종류(9-11)

Blackwidow·2020년 12월 17일
0

객체편!!!

1. reference type data 할당하기

  • 참조주소를 복사하기 때문에 서로 영향을 받는다.
const referenceTypeData = {a:1, b:2, c:3};
const copiedRtd = referenceTypeData; 
copiedRtd; // {a:1, b:2, c:3}
delete copiedRtd.a; 
copiedRtd; // {b:2, c:3}
referenceTypeData; // {b:2, c:3}

2. 얕은복사(Shadow merge) - Obj.assign()

  • 객체속성 자체를 복사하기 때문에 서로 영향을 받지 않는다.(일부는 영향을 받는다. 일부는 다음 코딩을 보고 다시 설명하겠다.)
let obj = {
  a: 1,
  b: 2,
};
let objCopy = Object.assign({}, obj);

console.log(objCopy); // result - { a: 1, b: 2 }
objCopy.b = 89;
console.log(objCopy); // result - { a: 1, b: 89 }
console.log(obj); // result - { a: 1, b: 2 }

위 코드를 보면 잘 복사된것으로 착각한다. 하지만 객체의 속성이 속성값을 어싸인으로 복사하면 말이 달라진다. 어떤 변화가 있는지 보자.

let obj = {
  a: 1,
  b: {
    c: 2,
  },
}
let newObj = Object.assign({}, obj);
console.log(newObj); // { a: 1, b: { c: 2} }

obj.a = 10;
console.log(obj); // { a: 10, b: { c: 2} }
console.log(newObj); // { a: 1, b: { c: 2} }

newObj.a = 20;
console.log(obj); // { a: 10, b: { c: 2} }
console.log(newObj); // { a: 20, b: { c: 2} }

newObj.b.c = 30;
console.log(obj); // { a: 10, b: { c: 30} }
console.log(newObj); // { a: 20, b: { c: 30} }

마지막 newObj.b.c = 30을 변경하였는데 원본인 obj.b.c도 함께 변경되었다. 왜 이렇게 되었을까? 자세히 보면 복사할때 b에 값을 어떻게 복사가 되었는지 의심할 수 있다. 결과를 봤을때에는 참조(주소)를 복사한것으로 추측할 수 있다. 이름처럼 얕은복사라 할 수 있겠다.

3. 깊은 복사(Deep merge) - JSON.parse(JSON.stringify())

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

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

obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 
  • Object.assign()으로 복사된 객체에 대한 단점을 보완할 수 있는 방법이다.

4. Object.assign() - 또다른 예시

const result1 = {
  B: {
    C: 'A1.B.C'
  }
}

const result2 = {
  B: {
    D: 'A2.B.D'
  }
}

Object.assign(result1, result2) 해보자.

{
  B: {
    D: 'A2.B.D'
  }
}
  • 의도된대로 나오지 않았다.
    Object.assign()은 result1에다가 result2를 합치는데 그 과정에서 result1와 result2의 키가 일치한다면 result1의 키에다가 result2의 일치하는키의 값으로 변경시켜버린다. 그래서 위의 결과가 나온다.
    우리가 원하는 제대로 된 병합(result1의 동일키의 값과 result2의 동일키와 같을 변경하지 않고 합치기)를 하고싶다.
    이 방법은 다음 블로그때 알아보기로 하자.

5. ES6 spread 연산자

it('여러 개의 객체를 병합할 수 있습니다.', function () {
    const A = {
      cohort: 7,
      duration: 4,
      mentor: 'hongsik',
    };

    const B = {
      time: '0156',
      status: 'sleepy',
      todos: ['coplit', 'koans'],
    };

    const merged = { ???, ??? }; // 답 : ...A ...B
  
    expect(merged).to.deep.equal({
      cohort: 7,
      duration: 4,
      mentor: 'hongsik'
      time: '0156',
      status: 'sleepy',
      todos: ['coplit', 'koans'],
    });
  });
  • 동일한 키가 없을때에는 이 방법을 사용해보자.
profile
javascript 공부하는 sumiindaeyo

0개의 댓글