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ディープコピーの実装例

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

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

推薦する

MySQLでインデックスエラーが発生する状況について簡単に説明します

以下に、トレーニング機関からのヒントと私自身の要約をいくつか示します。以下のインデックスの内容を説明...

よく使用される Linux コマンドの完全なリスト (推奨コレクション)

目次1. システム情報2. シャットダウン(システムのシャットダウン、再起動、ログアウト) 3. フ...

win10 mysql 5.6.35 winx64 無料インストールバージョン設定チュートリアル

mysql 5.6.35 winx64無料インストールバージョン構成チュートリアルwin10、具体的...

MySQL はどのようにしてマスターとスレーブの同期を実現するのでしょうか?

マスタースレーブ同期 (マスタースレーブレプリケーションとも呼ばれる) は、マスタースレーブデータの...

音楽プレーヤーアプリ(アプリケーションソフトウェア)の分析と再設計 美しい音楽プレーヤーインターフェースの設計方法

無線インタラクションにずっと興味があったので、今回は実践してみようと思います〜この分析と評価は iO...

HTML テーブルタグチュートリアル (24): 行の水平方向の配置属性 ALIGN

水平方向では、行の配置を左、中央、右に設定できます。基本的な構文<TR ALIGN="...

HTMLのテーブルの内容は中央に水平と垂直に表示されます

CSSスタイルファイルで指定 #class td /*表のテキストを左右上下に揃えるように設定する*...

MySQL GTID の総合概要

目次01 GTIDの紹介02 GTIDの仕組み03 GTIDの利点と欠点04 テスト環境構築05 テ...

CnBlogs カスタムブログスタイルの共有

半夜かけてようやくブログのスタイルを大体完成させることができました。ブログ全体が青を基調としていて、...

Eclipse は Tomcat を構成しますが、Tomcat には無効なポート解決策があります

目次1. EclipseがTomcatを構成する2. Tomcat の無効なポートの解決方法方法1:...

Linux クラウド サーバーに JDK と Tomcat をインストールするための詳細な手順 (推奨)

JDKをダウンロードしてインストールするステップ 1: まず、公式 Web サイト http://...

問題におけるJS演算子の調査

問題は、誰もが「メモリ リーク」について知っていることです。一般的なシナリオはいくつかあります。クロ...

TypeScript の関数

目次1. 関数の定義1.1 JavaScript の関数1.2 TypeScriptの関数2. オプ...

CentOs でノード バージョンを手動でアップグレードする方法

1. 対応するNode.jsパッケージを見つけます。https://nodejs.org/downl...