ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptの浅いコピーとディープコピー
浅いコピーとディープコピーは、JavaScriptでオブジェクトのコピーを作成する方法と、「コピー」で作成するデータを参照してください。この記事では、これらの方法の違いを深く掘り下げ、それらの実用的なアプリケーションを調査し、それらを使用するときに生じる可能性のある潜在的な落とし穴を明らかにします。
キーポイント
Object.assign()
次のコードの例を見てみましょう。新しく作成されたオブジェクトは、オペレーターを拡張することによって作成された{...originalObject}
のコピーです。これには、予想外の結果があります。
shallowCopyZoo
しかし、zoo
に正確に何があるか見てみましょう。プロパティ
<code class="language-javascript">let zoo = { name: "Amazing Zoo", location: "Melbourne, Australia", animals: [ { species: "Lion", favoriteTreat: "?", }, { species: "Panda", favoriteTreat: "?", }, ], }; let shallowCopyZoo = { ...zoo }; shallowCopyZoo.animals[0].favoriteTreat = "?"; console.log(zoo.animals[0].favoriteTreat); // "?",而不是 "?"</code>は元の値(文字列)であるため、値がコピーされます。ただし、
プロパティはオブジェクトの配列であるため、コピーされるのは、配列自体ではなく、その配列への参照です。 これは、コードベースに潜在的な問題を引き起こす可能性があり、大規模な変更に対処する場合に特に困難です。浅いレプリカでネストされたオブジェクトを変更すると、すべてが同じ参照を共有するため、元のオブジェクトやその他の浅いレプリカにも影響します。 ディープコピーは、既存のオブジェクトの正確なコピーである新しいオブジェクトを作成するためのトリックです。これには、参照ではなく、すべてのプロパティとネストされたオブジェクトをコピーすることが含まれます。ディープクローニングは、参照を共有しない2つの個別のオブジェクトが必要な場合に役立ち、1つのオブジェクトへの変更が他のオブジェクトに影響を与えないようにします。 プログラマーは、複雑なアプリケーションでアプリケーション状態オブジェクトを扱うときに、多くの場合、深いクローニングを使用します。以前の状態に影響を与えることなく新しい状態オブジェクトを作成することは、アプリケーションの安定性を維持し、元に戻す/redo機能を正しく実装するために重要です。 および メソッドは完璧ではありません。たとえば、 関数を作成して、オブジェクトを深くクローン化します。次に、元のオブジェクトに影響を与えることなく、
深い複製はデータの精度に大きな利点をもたらしますが、特定のユースケースごとに深い複製が必要かどうかを評価することをお勧めします。場合によっては、オブジェクト参照を管理するための浅いコピーまたはその他の手法がより適切である可能性があり、それによりパフォーマンスが向上し、複雑さが低下します。
JavaScript(FAQ) 拡張演算子は浅いコピーでどのように機能しますか? はい、JSONメソッドを使用して、JavaScriptでディープコピーを実行できます。 浅いコピーは、ネストされたオブジェクトへの第1レベルの属性と参照のみを複製します。したがって、元のオブジェクトにネストされたオブジェクトが含まれている場合、それらのネストされたオブジェクトの変更は、元のオブジェクトとコピーされたオブジェクトに影響します。これにより、コードの予期しない結果とエラーが発生する可能性があります。 JavaScriptでオブジェクトを深くコピーする最良の方法は、コードの特定の要件に依存します。オブジェクトにメソッドまたは特別なJavaScriptオブジェクトが含まれていない場合は、 いいえ、JavaScriptの拡張演算子は浅いコピーのみを実行します。最初のレベルの属性とネストされたオブジェクトへの参照をコピーします。深い複製を実行するには、別の方法またはライブラリを使用する必要があります。 深い複製は、特に大きなオブジェクトの場合、浅い複製よりも多くのリソースを消費する場合があります。これは、ディープコピーがすべてのネストされたオブジェクトに新しいインスタンスを作成し、より多くのメモリと処理能力を引き出すことができるためです。 JavaScriptのデータを管理するには、浅い複製と深い複製の違いを理解することが重要です。オブジェクトが相互にどのように相互作用するかに影響します。注意しないと、浅いコピーは、ネストされたオブジェクトの変更が元のオブジェクトとコピーされたオブジェクトに影響するため、予期しない結果とエラーにつながる可能性があります。一方、ディープコピーは、コピーオブジェクトが元のオブジェクトから完全に独立していることを保証します。 shallowCopyZoo
name
Strict Equality Operator(location
属性は両方で等しいが、オブジェクト自体は等しくないことに注意してください。 animals
<code class="language-javascript">let zoo = {
name: "Amazing Zoo",
location: "Melbourne, Australia",
animals: [
{
species: "Lion",
favoriteTreat: "?",
},
{
species: "Panda",
favoriteTreat: "?",
},
],
};
let shallowCopyZoo = { ...zoo };
shallowCopyZoo.animals[0].favoriteTreat = "?";
console.log(zoo.animals[0].favoriteTreat);
// "?",而不是 "?"</code>
ディープコピー
および
人気のあるライブラリフリーのディープコピー方法は、組み込みJSON.stringify()
を使用する方法JSON.parse()
JSON.stringify()
メソッドを使用することです。 JSON.parse()
parse(stringify())
などの特別なデータ型は文字列に変換され、未定義の値は無視されます。この記事のすべてのオプションと同様に、特定のユースケースに基づいてそれを考慮する必要があります。 Date
deepCopy
オブジェクトをコピーしてコピーしたオブジェクトを変更します。これは、参照を共有しない独立したオブジェクトを維持する際の深い複製の価値を示しています。 playerProfile
<code class="language-javascript">console.log(zoo.animals === shallowCopyZoo.animals)
// true
console.log(zoo === shallowCopyZoo)
// false</code>
深い複製ソリューションを提供するさまざまなサードパーティライブラリもあります。
関数は、ループ参照、機能、および特別なオブジェクトを正しく処理できます。
cloneDeep()
extend()
Immerライブラリは、React-Redux開発者向けに構築されており、オブジェクトを変更するための便利なツールを提供します。 [deep = true]
ディープコピーの欠点
結論Date
、RegExp
、DOM要素)。たとえば、関数を含むオブジェクトを深くコピーする場合、関数への参照がコピーされる場合がありますが、関数の閉鎖とその結合コンテキストはコピーされません。同様に、特別な機能を備えたオブジェクトは、深く複製すると一意の特性と動作を失う可能性があります。 JSON.parse(JSON.stringify(obj))
のような組み込みのメソッドには、関数を正しく処理できない、円形参照、または特別なオブジェクトなどの制限もあります。ディープレプリケーションをより効率的に処理するLodashのようなサードパーティライブラリがいくつかありますが、深い複製のために外部依存関係を追加することは必ずしも理想的ではないかもしれません。 _.cloneDeep()
この記事を読んでくれてありがとう。浅くて深い複製は、初心者が考えるよりもはるかに複雑です。各アプローチには多くの落とし穴がありますが、これらのオプションを確認して検討するために時間をかけて、アプリケーションとデータがあなたがどのように見えるかを保証することを保証します。 JavaScriptの浅い複製と深い複製の主な違いは何ですか?
浅い複製と深い複製の主な違いは、オブジェクトとしてプロパティを処理する方法です。浅いコピーでは、コピーされたオブジェクトは、元のオブジェクトと同じ参照をネストされたオブジェクトと共有します。これは、ネストされたオブジェクトの変更が元のオブジェクトとコピーオブジェクトに反映されることを意味します。一方、ディープレプリケーションは、ネストされたオブジェクトの新しいインスタンスを作成します。つまり、複製されたオブジェクト内のネストされたオブジェクトの変更は、元のオブジェクトに影響しません。
JavaScriptの拡張演算子(…)は通常、浅いコピーに使用されます。あるオブジェクトのすべての列挙可能なプロパティを別のオブジェクトにコピーします。ただし、ネストされたオブジェクトへの最初のレベルの属性と参照のみをコピーします。したがって、ネストされたオブジェクトの変更は、元のオブジェクトとコピーされたオブジェクトに影響します。
深いコピーにJSONメソッドを使用できますか?
JSON.stringify()
とJSON.parse()
メソッドの組み合わせにより、オブジェクトの深いコピーが作成されます。 JSON.stringify()
オブジェクトを文字列に変換し、JSON.parse()
文字列を新しいオブジェクトに解析します。ただし、この方法には、メソッドをコピーせず、Date
、RegExp
、Map
、Set
などの特別なJavaScriptオブジェクトには適していないため、いくつかの制限があります。 浅い複製の制限は何ですか?
Object.assign()
メソッドは浅いコピーでどのように機能しますか? Object.assign()
メソッドは、ターゲットオブジェクトに1つ以上のソースオブジェクトのすべての列挙可能なプロパティの値をコピーするために使用されます。ターゲットオブジェクトを返します。ただし、浅いコピーを実行します。つまり、最初のレベルのプロパティとネストされたオブジェクトへの参照のみをコピーすることを意味します。 JavaScriptでオブジェクトを深くコピーする最良の方法は何ですか?
JSON.stringify()
とJSON.parse()
メソッドの組み合わせを使用できます。より複雑なオブジェクトの場合、深いクローン機能を提供するLodashのようなライブラリを使用することをお勧めします。 ディープコピーに拡張オペレーターを使用できますか?
深い複製のパフォーマンスへの影響は何ですか?
深い複製で円形の参照を扱う方法は?
JSON.stringify()
やJSON.parse()
などのディープコピーメソッドは、円形の参照を処理せず、エラーをスローします。オブジェクトのプロパティがオブジェクト自体を参照すると、円形の参照が発生します。円形の参照を処理するには、Lodashなどのそれをサポートするライブラリを使用する必要があります。 なぜ浅いコピーとディープコピーの違いを気にする必要があるのですか?
以上がJavaScriptの浅いコピーとディープコピーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。