jsのディープコピーを理解しましょう

jsのディープコピーを理解しましょう

js ディープコピー

本題に入る前に、データがどのように保存されるかを理解する必要があります。

データ保存方法

それについて説明する前に、まず値型と参照型がどのように格納されるかを知っておく必要があります。

JavaScript には 2 種類のデータがあります。

値の型: StringNumberBooleanNullUndefinedSymbol

スタックメモリに格納される単純なデータセグメントで、データサイズが決定され、メモリ空間のサイズを割り当てることができます。

参照データ型: Object(ArrayFunction

ヒープ メモリに格納されているオブジェクトの場合、ポインターはスタック メモリに格納され、このポインターはヒープ メモリ内の場所を指します。次に、ヒープ メモリから必要なデータを取得します。

ストレージは次のとおりです。

ここに画像の説明を挿入

浅いコピー/深いコピーとは何か

保存方法についてお話しした後は、浅いコピーと深いコピーについてお話ししましょう

コピーはよくコピー、ctrl+c、ctrl+vなどと呼ばれますが、例を見てみましょう

値型と参照型にそれぞれ値を割り当てる場合。

     変数a = 5
     var b = a
     b += 5
     コンソールログ('a=' + a,'b=' + b)
     var arr = [1,2,3]
     var brr = arr
     brr.push(10)
     console.log("arr は",arr)
     console.log("brr is",brr)

ここに画像の説明を挿入

現象:値型は互いに影響を及ぼさないが、配列(参照型)brr配列は要素を追加するとarr配列を変更することがわかりました。

説明と分析: 浅いコピーは参照型でのみ発生します。参照型で単純な割り当てを実行すると、ヒープ メモリへのポインターのみが割り当てられます。これを浅いコピーと呼びます。ディープ コピーは、アドレス ポインターではなく、参照型の完全なコピーです。

次の回路図の浅いコピーを取得します。

ここに画像の説明を挿入

一般的なディープコピーの実装

したがって、参照型を割り当てるときは、元のデータに影響を与える浅いコピーを作成してはなりません。次にディープコピーを行う必要があります

1. JSON.stringifyとJSON.parseを通じて

配列とオブジェクトは深くコピーできますが、関数はコピーできません。オブジェクトまたは配列のネストされたコピーを作成できます。

デメリット: オブジェクト内のメソッドのディープコピーは不可能

使用

     var brr = JSON.parse(JSON.stringify(arr))

例:

  var arr = {
         名前:「ロマンティック コーダー」
         年齢: 20,
         住所: ['江西', '長沙'],
         友達:
             友人1: '張三'、
             友人2: '李思'
         },
         関数(){
             console.log("私はロマン主義の対象です")
         }
     }
     var brr = JSON.parse(JSON.stringify(arr))
     brr.name='無法犯罪者、張三'
     brr.adress[0]='長沙'
     console.log("arr は", arr)
     console.log("brr is", brr)

ここに画像の説明を挿入

2. スプレッド演算子

オブジェクトの構造割り当て機能方式を活用します。

デメリット: オブジェクト内のネストされたオブジェクトのディープコピーはありません。これは、参照オブジェクトの1つのレイヤーのみをディープコピーするのと同じです。

使用:

     var brr = {...arr}

例:

  var arr = {
         名前:「ロマンティック コーダー」
         年齢: 20,
         住所: ['江西', '長沙'],
         友達:
             友人1: '張三'、
             友人2: '李思'
         },
         関数(){
             console.log("私はロマン主義の対象です")
         }
     }
     var brr = {...arr}
     brr.name='無法犯罪者、張三'
     brr.adress[0]='長沙'
     console.log("arr は", arr)
     console.log("brr is", brr)

ここに画像の説明を挿入

3. 手書きの再帰的なディープコピー機能

完璧な解決策

関数:

  //再帰を使用してディープコピーを実装する function deepClone(obj) {
         //コピーされた obj がオブジェクトか配列かを判断します var objClone = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") { //obj は空にできず、null もオブジェクトであるため、オブジェクトまたは配列である必要があります。
             for (キー in obj) {
                 obj.hasOwnProperty(キー) の場合 {
                     if (obj[key] && typeof obj[key] === "object") { //objの属性値は空ではなく、まだオブジェクトなので、ディープコピーを作成します。objClone[key] = deepClone(obj[key]); //再帰的にディープコピーを作成します。} else {
                         objClone[key] = obj[key]; //直接コピー}
                 }
             }
         }
         objClone を返します。
     }

例:

      var arr = {
         名前:「ロマンティック コーダー」
         年齢: 20,
         住所: ['江西', '長沙'],
         友達:
             友人1: '張三'、
             友人2: '李思'
         },
         楽しい: 関数(){
             console.log("私は " + this.name + " のオブジェクトです")
         }
     }
     var brr = deepClone(arr)
     brr.name = '無法者張三'
     brr.adress[0] = '長沙'
     console.log("arr は", arr)
     arr.fun()
     console.log("brr is", brr)
     brr.fun()
 ​
     //再帰を使用してディープコピーを実装する function deepClone(obj) {
         //コピーされた obj がオブジェクトか配列かを判断します var objClone = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") { //obj は空にできず、null もオブジェクトであるため、オブジェクトまたは配列である必要があります。
             for (キー in obj) {
                 obj.hasOwnProperty(キー) の場合 {
                     if (obj[key] && typeof obj[key] === "object") { //objの属性値は空ではなく、まだオブジェクトなので、ディープコピーを作成します。objClone[key] = deepClone(obj[key]); //再帰的にディープコピーを作成します。} else {
                         objClone[key] = obj[key]; //直接コピー}
                 }
             }
         }
         objClone を返します。
     }

ここに画像の説明を挿入

要約する

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • jsオブジェクトの浅いコピーと深いコピーの詳細な説明
  • JavaScript配列のディープコピーとシャローコピーの2つの方法
  • JavaScript でのオブジェクトのディープコピー
  • JS の配列のディープコピーの実装方法の分析
  • JavaScriptディープコピー(deepClone)の詳しい説明
  • js ディープコピー関数
  • JavaScript の基本: 浅いコピーと深いコピー (浅いコピーと深いコピー)
  • JSで浅いコピーと深いコピーを実装するためのコードの詳細な説明
  • javascript ディープコピー
  • JavaScriptディープコピーの実装例

<<:  ユーザー エクスペリエンス デザイナーとは誰ですか?

>>:  入力タイプとは何を意味し、入力を制限する方法

推薦する

iOS スタイルの選択ボックスの開閉機能を実装するための純粋な CSS

1 効果デモアドレス: https://www.albertyy.com/2020/7/check...

MySQL での GROUP_CONCAT の使用例の分析

この記事では、例を使用して、MySQL で GROUP_CONCAT を使用する方法について説明しま...

Linux で MySQL のデフォルト エンコーディングを変更する方法

開発プロセス中に、MySQL データベースを復元した後にデータベース データに文字化けが発生した場合...

JavaScriptはスタック構造の詳細なプロセスを実装する

目次1. スタック構造を理解する2. スタック構造のカプセル化3. 10進数を2進数に変換する1. ...

Vue 計算プロパティ実装トランスクリプト

この記事では、Vueの計算プロパティ実装レポートカードを参考に共有します。具体的な内容は次のとおりで...

Docker コンテナのネットワーク障害に対する 6 つの解決策

Docker コンテナのネットワーク障害に対する 6 つの解決策注: 以下の方法は、コンテナ内のパブ...

ホストがアクセスできるようにMySQLの権限を変更する方法

mysqlのリモートアクセス権を有効にするデフォルトでは、MySQL ユーザーにはリモート アクセス...

Dockerコンテナの起動失敗を解決する方法

質問: コンピュータを再起動した後、docker の mysql コンテナを再起動できません。原因が...

ORM を使用して MySQL にデータを追加する手順

【序文】 ORM を使用してデータベース内のデータを操作する場合、前提として、新しい ORM モデル...

フォント名に従ってフォントを呼び出すと、ブラウザに必要なフォントが表示されます。

質問 1: ブラウザに必要なフォントを表示するように指示するにはどうすればよいでしょうか? フォント...

Docker を使用した nGrinder パフォーマンス テスト プラットフォームの導入プロセスの分析

nGrinderとは何ですか? nGrinder は、スクリプトの作成、テストの実行、監視、結果レポ...

UbuntuはPythonスクリプトのサンプルコードを定期的に実行する

オリジナルリンク: https://vien.tech/article/157序文この記事では、Ub...

Linux での MySQL データベースのアンインストール

Linux で MySQL データベースをアンインストールするにはどうすればいいですか? 以下では、...

Vue3 における provide と inject の使用法と原則

序文:親コンポーネントと子コンポーネント間でデータを渡す場合、通常は props と emittin...

シンプルな広告ウィンドウを実現するjs

この記事では、参考までに、シンプルな広告ウィンドウを実装するためのjsの具体的なコードを紹介します。...