ホームページ  >  に質問  >  本文

JavaScript オブジェクトを適切に複製するにはどうすればよいですか?

<p>オブジェクト <code>x</code> があります。これをオブジェクト <code>y</code> としてコピーして、<code>y</code> への変更によって <code>x</code> が変更されないようにしたいと考えています。組み込み JavaScript オブジェクトから派生したオブジェクトをコピーすると、余分な不要なプロパティが作成されることに気づきました。私は独自のテキストで構築したオブジェクトの 1 つをコピーしているので、これは問題ではありません。 </p> <p>JavaScript オブジェクトを適切に複製するにはどうすればよいですか? </p>
P粉334721359P粉334721359444日前473

全員に返信(2)返信します

  • P粉691958181

    P粉6919581812023-08-24 09:44:45

    オブジェクトで Date、Function、Unknown、regExp、または Infinity を使用していない場合、非常に単純な行は JSON.parse(JSON.stringify(object))< /代码> です。

    リーリー

    これは、オブジェクト、配列、文​​字列、ブール値、数値を含むすべてのタイプのオブジェクトに適用されます。

    ワーカーとの間でメッセージをパブリッシュするときに使用される構造化クローン アルゴリズム ブラウザ

    については、この記事も参照してください。ディープ クローン作成機能も含まれています。

    返事
    0
  • P粉122932466

    P粉1229324662023-08-24 00:44:32

    2022年更新

    構造化クローニングと呼ばれる新しい JS 標準があります。多くのブラウザで動作します (「使用できますか 」を参照)。 リーリー

    古い答え

    これを JavaScript で任意のオブジェクトに対して実行することは、決して単純でも簡単でもありません。オブジェクトのプロトタイプからプロパティを誤って取得するという問題に遭遇します。プロパティは、新しいインスタンスにコピーされるのではなく、プロトタイプに残される必要があります。たとえば、

    clone メソッドを Object.prototype に追加する場合 (一部の回答が示唆しているように)、そのプロパティを明示的にスキップする必要があります。しかし、Object.prototype にその他のメソッドが追加されている場合や、知らない他の中間プロトタイプがある場合はどうなるでしょうか?この場合、コピーすべきではないプロパティをコピーしているため、hasOwnProperty メソッドを使用する必要があります。

    列挙できないプロパティに加えて、非表示のプロパティを持つオブジェクトをコピーしようとすると、さらに厄介な問題に遭遇します。たとえば、

    prototype は関数の隠し属性です。さらに、オブジェクトのプロトタイプはプロパティ __proto__ を通じて参照されますが、これも非表示であり、ソース オブジェクトのプロパティを反復する for/in ループによってコピーされません。 __proto__ は Firefox の JavaScript インタプリタに固有であり、他のブラウザでは異なる可能性があると思いますが、アイデアは理解できますか。すべてが数えられるわけではありません。非表示のプロパティの名前がわかっている場合は、それをコピーできますが、それを自動的に検出する方法はわかりません。

    洗練されたソリューションを探す際のもう 1 つの障害は、プロトタイプの継承を正しく設定するという問題です。ソース オブジェクトのプロトタイプが

    Object の場合は、{} を使用して新しい汎用オブジェクトを作成するだけですが、ソース オブジェクトのプロトタイプが Object の場合は、子孫コード>、その場合、hasOwnProperty フィルターを使用してスキップされたプロトタイプ内の他のメンバー、またはそもそも列挙可能ではなかったプロトタイプ内の他のメンバーが失われます。解決策の 1 つは、ソース オブジェクトのコンストラクター プロパティを呼び出して初期コピー オブジェクトを取得し、その後プロパティをコピーすることですが、それでも列挙不可能なプロパティは取得できません。たとえば、Date オブジェクトは、そのデータを非表示メンバーとして保存します。 リーリー

    d1

    の日付文字列は、d2 より 5 秒後になります。ある Date を別の Date と同一にする方法は、setTime メソッドを呼び出すことですが、これは Date クラスに固有です。この問題に対する確実な普遍的な解決策はないと思いますが、間違っていることは幸いです。

    一般的なディープ コピーを実装する必要があったとき、私は最終的に妥協して、通常の ObjectArrayDate、をコピーするだけでよいと考えました。 <代码>String、<代码>Number、または <代码>Boolean。最後の 3 つのタイプは不変なので、変更されることを気にせずに浅いコピーを実行できます。さらに、Object または Array に含まれる要素も、このリストの 6 つの単純型の 1 つであると仮定します。これは次のようなコードで実行できます:

    リーリー

    オブジェクトと配列内のデータがツリー構造を形成している限り、前述の 6 つの単純な型には上記の関数で十分です。つまり、オブジェクト内の同じデータは 1 回だけ参照されます。例えば:### リーリー

    これは JavaScript オブジェクトを処理できませんが、投げたものだけで動作すると考えない限り、多くの目的には十分かもしれません。

    返事
    0
  • キャンセル返事