Deep copyの注意点
環境
Node.js v14.2.0
Date型, function, undefined, symbolを使う場合
例(コード)
const obj = { s: 'bar', n: 13, ns: '13', d: new Date(), u: undefined, f: () => {}, sy: Symbol(''), nu: null, a: [new Date(), undefined, null, () => {}, Symbol(''), []] } const copy = JSON.parse(JSON.stringify(obj)) typeof obj.d // 'object' typeof copy.d // 'string' copy // { // s: 'bar', // n: 13, // ns: '13', // d: '2020-05-16T15:01:38.298Z', // nu: null, // a: [ '2020-05-16T15:01:38.298Z', null, null, null, null, [] ] // }
原因
Boolean、 Number、 String の各オブジェクトは、文字列化の際に慣習的な変換セマンティクスに従い、対応するプリミティブ値に変換されます。 変換の際に undefined、 関数 (Function)、シンボル (Symbol) は有効な JSON 値ではありません。変換中にそのような値に遭遇した場合は、 (オブジェクトの中で発見された場合は) 省略されたり、 (配列の中で見つかった場合は) null に変換されたりします。
途中でエラーが発生した場合
- エラー発生時点で中断するため、以降の処理は発生しない
var target = Object.defineProperty({}, 'foo', { value: 1, writable: false }); // target.foo は読み取り専用のプロパティ Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 }); // TypeError: "foo" is read-only // target.foo に代入しようとすると、この例外が発生する console.log(target.bar); // 2, 一番目のコピー元オブジェクトはコピーされている console.log(target.foo2); // 3, 二番目のコピー元の最初のプロパティもコピーされている console.log(target.foo); // 1, ここで例外が発生(値は変更されていない) console.log(target.foo3); // undefined, assign メソッドが終了したので foo3 はコピーされない console.log(target.baz); // undefined, 三番目のコピー元もコピーされない