JavaScriptオブジェクトの深いコピー例と浅いコピー例を詳しく解説

零下一度
リリース: 2017-04-19 15:58:00
オリジナル
1189 人が閲覧しました

階層的な観点から見ると、オブジェクトのコピーは、浅いコピーと深いコピーに単純に分けることができます。その名前が示すように、浅いコピーは、オブジェクトのレイヤーのプロパティのみをコピーすることを指し、オブジェクト内のオブジェクトのプロパティはコピーされません。オブジェクトのディープコピーは、オブジェクト内にネストされたオブジェクトのプロパティをコピーします。この記事は、オブジェクトのコピーに関する浅いコピーから深いコピーまでのいくつかの経験をまとめたものです。興味のある友人は一緒に学ぶことができます

序文

階層的な観点から見ると、オブジェクトのコピーは簡単に浅いコピーに分けることができます。コピーとディープ コピー。ディープ コピーは、その名前が示すように、オブジェクトの 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
ログイン後にコピー

JavaScriptオブジェクトの深いコピー例と浅いコピー例を詳しく解説

配列のコピーを正しく実装してコンストラクターを保持できますが、注意していれば、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 オブジェクトのコピー関数を取得できます: JavaScriptオブジェクトの深いコピー例と浅いコピー例を詳しく解説

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オブジェクトの深いコピー例と浅いコピー例を詳しく解説

オブジェクト指向プログラミング言語、そのコアはオブジェクトなので、オブジェクトの関連する操作を深く理解し、類似点と相違点を垂直に比較することは、学習プロセスに非常に有益です。

以上がJavaScriptオブジェクトの深いコピー例と浅いコピー例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
js
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート