web-dev-qa-db-ja.com

オブジェクトのディープクローン作成のためのObject.assignとJSON.parse(JSON.stringify(obj))の違いは何ですか?

私は知りたいの違いがあります

Object.assign({}, obj)

そして

JSON.parse(JSON.stringify(obj))

オブジェクトのディープクローンを作成しますか?アイデアがあれば誰でも説明できますか?

28
Ram

違いは

Object.assign({}, obj)

deep ではなく shallow copy を作成しますが、

JSON.parse(JSON.stringify(obj))

serializes JSON文字列としてオブジェクトをデシリアライズし、効果的にディープコピーを作成します。

すべてのプロパティがプリミティブ値を指している場合、またはコピーによって参照されるオブジェクトを変更する意図がない場合は、浅いコピーで十分です。変更すると、元のコピーと浅いコピーの両方に変更が表示されます。これらは両方とも同じオブジェクトを参照するためです。

> let a = { k: { h: 1 } };
> let b = Object.assign({}, a);
> b.k.h = 2;
> a
{ k: { h: 2 } }
> b
{ k: { h: 2 } }

もちろん、オリジナルに影響を与えることなく、コピー自体を変更できます。

> b.j = 4
> b.k = { new: 'object' }
> a
{ k: { h: 2 } }
> b
{ k: { new: 'object' }, j: 4 }

一方、serialize-deserializeトリックは、すべてがゼロから作成されるディープコピーを作成します。

> let c = JSON.parse(JSON.stringify(b));
> c
{ k: { h: 2 } }
> c.k.h = 3
> c
{ k: { h: 3 } }
> a
{ k: { h: 2 } }
> b
{ k: { h: 2 } }

アイデンティティを検査する別の方法は、厳密な等価性を使用することです:

> let a = { k: { h: 1 } };
> let b = Object.assign({}, a);
> a.k === b.k  // both point to the same object
true
> let c = JSON.parse(JSON.stringify(b));
> c.k === b.k  // different objects
false
38
Ilja Everilä