JavaScript の浅いコピーと深いコピー、およびオブジェクトと JSON 形式の変換 JSON.stringify、JSON.parse

   浅いコピー: 参照型の場合、2 つの参照型が同じアドレスを指し、一方を変更すると他方もそれに応じて変更されることを意味します。


   たとえば、ku の変数値が {age : 18} に設定されている場合、angel の変数値は ku を指します。スタックメモリでは angel のメモリアドレスは ku のメモリアドレスと同じです。ヒープメモリでは、angel のメモリアドレスは ku と同じです。それらは同じオブジェクトです。



ここに画像の説明を挿入



   クエイジの属性値を変更すると、それに応じてエンジェルエイジの属性値も変更されます。



ここに画像の説明を挿入



   ディープコピー: 参照型の場合、参照型はコピー後の新しいメモリ アドレスを指し、2 つのオブジェクトの変更は相互に影響しません。


   まず、JSON (JavaScript Object Notation) について簡単に説明します。JSON (JavaScript Object Notation) は、JavaScript で値やオブジェクトを表現するための一般的なデータ形式であり、その本質は特定の仕様に準拠した文字列です。JSON の優れた特性により、特にフロントエンドとバックエンドの対話において、他の言語とのデータ交換が非常に簡単です。


   前回のブログでも、JS のデシリアライズに関するクローラ プロジェクトの事例を紹介しましたが、ここでは、次のシリアル化とデシリアライズの例を使用してディープ コピーとシャロー コピーの違いを説明し、その後、シリアル化とデシリアライズについて詳しく説明します。用途。


   JSON.stringifyでJSON文字列形式に変換(シリアル化)



ここに画像の説明を挿入



   次に、JSON.parse (逆シリアル化) を通じてそれを angel に割り当てます。ku age が変更されても、angel age の値は変更されません。つまり、スタックメモリとヒープメモリにおいて、kuとangelは独立したメモリアドレスとオブジェクトオブジェクトを持ち、変更が生じても両者は相互に影響を与えない。



ここに画像の説明を挿入



   == 注: 基本タイプの割り当てはディープ コピーに似ていますが、ディープ コピーではありません。==



ここに画像の説明を挿入



   JSON.stringify(obj) メソッドを使用すると、オブジェクト obj の JSON 文字列データが返されますが、JavaScript 言語自体に属する非データ属性 (オブジェクト メソッド、シンボル タイプ、未定義の属性など) は JSON.stringify によってスキップされます。 。



   表示されます。出力は空のコンテンツです

ここに画像の説明を挿入



   すべてのオブジェクトを JSON 形式に変換できるわけではないため、オブジェクト間に循環参照がある場合、変換は失敗します。失敗の理由は、教師が生徒を参照し、生徒が教師を参照することです。



ここに画像の説明を挿入



   オブジェクトの個々のプロパティのみを JSON 形式に変換する場合、またはループ アプリケーションでプロパティを表示する場合は、 let json = JSON.stringify(obj[,replacer,space]) を渡すことができます。ここで、パラメーター obj:エンコードされるオブジェクト; replacer : エンコードされる属性の配列またはマッピング関数 function(k,v); space: 書式設定に使用されるスペースの数。



  
ここに画像の説明を挿入



   2 番目のパラメーターに配列を渡す場合、JSON.stringify は配列内の名前のみを JSON 形式に変換するため、計算オブジェクト内に循環参照が存在し、形式も正常に変換されます。


   ループ アプリケーションの外側ですべてのオブジェクト プロパティをシリアル化したい場合は、オブジェクトのすべてのプロパティ名を配列に書き込むだけで済みます。これはオブジェクトのサブオブジェクトにも有効です。


   実行結果は以下の通りですが、まだ問題があり、オブジェクトのプロパティが多すぎると配列が非常に長くなり、コードが非常に長くなる可能性があるため、この場合はマッピング関数を使用する必要があります。



ここに画像の説明を挿入



   マッピング機能:置換として配列の代わりに、(キー、値) をパラメータとして受け取り、対応するプロパティをシリアル化する方法を決定する関数を作成できます。


   たとえば、循環参照を解決する場合、参照プロパティを除外します。未定義の値を持つ属性は JSON.stringify によって無視されるため、不要な属性をすべて簡単に除外できます。

ここに画像の説明を挿入



   書式設定に使用されるスペースの数:JSON.stringify(value, replacer, space) の 3 番目のパラメータ space では、JSON 文字列のインデントのスペース数を指定でき、一般的に使用される値は 2 と 4 です。上の例では、インデントスペースの数が指定されていないため、フォーマットされた JSON 文字列はフォーマットされていません。


   このようにして、出力がより明確にインデントされます



ここに画像の説明を挿入



   カスタム toJSON メソッド:toString と同様に、オブジェクトの toJSON メソッドはシリアル化中に呼び出され、このメソッドをオーバーライドすることでシリアル化メソッドを変更できます。


   オブジェクトの toJSON メソッドを書き換えた後、stringify を使用した結果が変化していることがわかります。必要に応じて toJSON メソッドを書き換えて、望ましい結果を達成できます。



ここに画像の説明を挿入



   JSON.parse:デシリアライズの例は以前簡単に紹介しましたが、今回は JSON 文字列をオブジェクトに変換する方法を詳しく紹介します。構文: let obj = JSON.parse(str,[reviver]) 。str 解析する JSON 文字列。各 (キー、値) ペアに対して呼び出され、値を変換できるオプションの関数 function(key,value) を復活させます。



ここに画像の説明を挿入



   リバイバーを使う, たとえば、文字列「{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}」をオブジェクトに変換したい場合、エラーが報告されます。その理由は、日付属性が Date オブジェクトではなく文字列に変換されるためです。



ここに画像の説明を挿入



   これには、reviver 関数を使用して日付を Date オブジェクトに変換する必要があります。



ここに画像の説明を挿入



   レシーバーはネストされたオブジェクトでも使用できます



ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_48591974/article/details/129792650