階層的な観点から見ると、オブジェクトのコピーは、浅いコピーと深いコピーに単純に分けることができます。その名前が示すように、浅いコピーは、オブジェクトのレイヤーのプロパティのみをコピーすることを指し、オブジェクト内のオブジェクトのプロパティはコピーされません。オブジェクトのディープコピーは、オブジェクト内にネストされたオブジェクトのプロパティをコピーします。この記事は、オブジェクトのコピーに関する浅いコピーから深いコピーまでのいくつかの経験をまとめたものです。興味のある友人は一緒に学ぶことができます
序文
階層的な観点から見ると、オブジェクトのコピーは簡単に浅いコピーに分けることができます。コピーとディープ コピー。ディープ コピーは、その名前が示すように、オブジェクトの 1 つのレイヤーのプロパティのみがコピーされ、オブジェクト内のオブジェクトのプロパティはコピーされません。オブジェクトのプロパティは、オブジェクト内でレイヤーごとにネストされます。
オブジェクトをコピーするときは、オブジェクトのプロパティをコピーすることに加えて、オブジェクトのコンストラクター プロパティが保持されるかどうか、および各データ型 (JavaScript の一般的なデータ型には、文字列、数値、ブール値、データなど) があるかどうかも考慮する必要があります。 、RegExp、Array、Function、Object)はすべて正しいコピーを実現します。プロジェクトでは、実際の状況に基づいて、どのレベルのレプリケーションを達成する必要があるかを決定できます。
この記事は、浅いコピーから深いコピーまで、単純な属性のみのコピーから Function や RegExp などの複雑な属性のコピーまで、オブジェクトのコピーに関する私の経験の一部をまとめたもので、レイヤーごとに進みます。文中に不適切な点がございましたら、ご指摘いただければ幸いです。
Text
浅いコピー
浅いコピーは、オブジェクトの各属性を順番にコピーするだけであり、これらの属性を再帰的にコピーすることはありません。以下は単純な浅いコピーの実装です。
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return obj; for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
注意深く見てみると、上記のメソッドの欠陥を見つけるのは難しくありません:
1. 配列の浅いコピーは正しく実装できません
2. コピー操作によりオブジェクトのコンストラクター属性が失われます
わかりました。 、問題を発見しました。ターゲットを絞った方法で解決する必要があるだけで、オブジェクトを浅くコピーするかなり完璧な方法が誕生しました。
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return ; var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
ブラウザでテストしてください:
var arr1 = [0,1,2]; console.log(arr1); console.log(shadowCopy(arr1)); var arr2 = [0,1,2,[3,4,5]], arr2Copy = shadowCopy(arr2); console.log(arr2); console.log(arr2Copy); arr2Copy[3][0] = 6; console.log(arr2[3][0]); //6
配列のコピーを正しく実装してコンストラクターを保持できますが、注意していれば、arr2Copy[3] と arr2[ 3] オブジェクトを指します。一方を変更すると、もう一方も変更されます。私たちが達成したいのはレプリケーションですが、これはレプリケーションではありません。
これは浅いコピーの欠点の 1 つです。ディープ コピーがこの問題をどのように解決するかを見てみましょう。
ディープコピー
ディープコピーには再帰の層が必要で、オブジェクトのプロパティのプロパティを含む、オブジェクトのすべてのプロパティをコピーします....(Halo~)
単にプロパティをコピーするだけの場合そのコンストラクターは、関数、正規、Data などの特別なデータ型を考慮する必要はありません。次に、わずか 2 行のコードで、ディープ コピーを行うための小さなトリックを示します。ほとんどの場合、上記で要件を満たすことができますが、関数や正規表現などの特殊なデータ型を考慮する必要がある場合や、現在の環境が JSON をサポートしていない場合は、上記の方法が適用されない場合があります。現時点では、次のように再帰を通じてオブジェクトのディープ コピーを実現できます:
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var str = JSON.stringify(obj); return JSON.parse(str); }
上記の例で最初のテスト:
素晴らしい!多次元配列のコピーが正しく実現でき、次に関数と正規表現のコピーが実現できるかどうかを確認します。 !
少し整理すると、より一般的な JS オブジェクトのコピー関数を取得できます:
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(typeof obj[prop] === 'object'){ if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){ newObj[prop] = obj[prop]; } else { //递归 newObj[prop] = deepCopy(obj[prop]); } } else { newObj[prop] = obj[prop]; } } return newObj; }
オブジェクト指向プログラミング言語、そのコアはオブジェクトなので、オブジェクトの関連する操作を深く理解し、類似点と相違点を垂直に比較することは、学習プロセスに非常に有益です。
以上がJavaScriptオブジェクトの深いコピー例と浅いコピー例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。