javascript Deep copyとShallow copyの違い

環境

Node.js v14.2.0

結論

  1. Deep copyはネストしているObjectもcopyする
  2. Shallow copyはネストしているObjectは参照する
  3. Deep copyShallow copyともに、ネストしていないObjectはcopyする
  4. copyした場合、別の値を参照しているため、片方を変更しても、もう一方は影響を受けない
  5. 参照した場合、同じ値を参照しているため、片方を変更すると、もう一方も影響を受ける

例(がぞう)

ネストしているとは

  • ネストしているとは赤の範囲です
  • 青はネストしていません

f:id:kazuki_nakamura:20200516221241j:plain

参照の場合(結論2)

ある一つの値を参照する。 f:id:kazuki_nakamura:20200516231142p:plain

copyした場合(結論1, 3)

ある一つの値を複製し、別々に参照する。 f:id:kazuki_nakamura:20200516231137p:plain

例(コード)

function test() {
  'use strict';

  let obj1 = { a: 0 , b: { c: 0}};
  let obj2 = Object.assign({}, obj1);
  console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
  
  obj1.a = 1;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
  
  obj2.a = 2;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
  
  obj2.b.c = 3;
  console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
  console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}
  
  // Deep Clone
  obj1 = { a: 0 , b: { c: 0}};
  let obj3 = JSON.parse(JSON.stringify(obj1));
  obj1.a = 4;
  obj1.b.c = 4;
  console.log(JSON.stringify(obj1)); // { a: 4, b: { c: 4}}
  console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
}

test();

参考(mozilla)

developer.mozilla.org

Object.assign() はプロパティの値をコピーするため、深い複製を行うには別な方法を使用する必要があります。元の値がオブジェクトへの参照である場合、参照の値のみをコピーするからです。