JS のディープコピーとシャローコピーの詳細

JS のディープコピーとシャローコピーの詳細

1. 浅いコピーとはどういう意味ですか?

浅いコピーとは、ヒープ内のコンテンツを指す参照をコピーせずに、スタックに格納されているデータへの参照のみをコピーすることです。複数のデータの浅いコピーでは、ヒープ内の同じコンテンツを指す複数の参照がコピーされます。データの浅いコピーが変更されると、つまり、ヒープ内の参照によって指されるコンテンツが変更されると、ここで参照によって指される他のデータも変更されます。

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = obj とします。
objA.a = 'a';

console.log(obj.a); // 'a'
console.log(objA.a); // 'a'

2. ディープコピーとはどういう意味ですか?

ディープ コピーは、ヒープの内容をコピーして新しいオブジェクトを作成します。複数のディープ コピーは複数の異なるオブジェクトになります。つまり、それらは異なる参照を持ち、異なるヒープ コンテンツを指します。

3. ディープコピーを使用する理由

通常の開発では、データの送受信が行われることがあります。送信されたデータを受信した後、データの処理と変換は避けられません。元のデータ構造を破壊しないように、ディープコピーを使用してデータをコピーし、生成された新しいデータを処理することができます。ディープコピーは、複数の参照を変更した後の参照の混乱の問題を防ぐこともでき、 BUGの可能性を減らします。

4. ディープコピーのためのいくつかの方法

実装方法1: JSONシリアル化とデシリアル化

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

let objA = JSON.parse(JSON.stringify(obj)); //JSON のシリアル化と逆シリアル化 objA.a = 'a';

コンソールログ(obj.a); // 1
console.log(objA.a); // 'a'

JSONシリアル化とデシリアル化ではディープコピーを実現できますが、注意すべき欠点がいくつかあります。

  • dateオブジェクトは日付文字列に変換されます
  • プロトタイプにアクセスできない
  • undefinedプロパティをコピーできません
  • NANと無限大はNULLに変換されます
d1 = new Date() とします。
obj = {
    d1、
    d2: 未定義、
    d3:NaN
}
objD = JSON.parse(JSON.stringify(obj)); とします。
コンソールログ(obj) 
コンソール.log(objD)

実装方法2: Object.assign()

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = Object.assign(obj); とします。
objA.a = 'a';

コンソールログ(obj.a); // 1
console.log(objA.a); // 'a'

Object.assign()ディープコピーを実現できますが、より深いオブジェクト参照の浅いコピーのみを作成します。

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = Object.assign(obj); とします。
objA.c.c1 = 'c1'; //Object.assign() は単なるディープコピーです。

console.log(obj.c.c1); // 'c1'
console.log(objA.c.c1); // 'c1'

実装方法3: 拡張演算子

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = {...obj} とします。
objA.a = 'a';

コンソールログ(obj.a); // 1
console.log(objA.a); // 'a'

スプレッド演算子「 」はディープコピーを実現できますが、より深いオブジェクト参照の浅いコピーのみを作成します。

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = {...obj} とします。
objA.c.c1 = 'c1'; //拡張演算子 "..." は Object.assign() と同じですが、ディープ コピーのレイヤーは 1 つしかなく、複数レイヤーのディープ コピーを持つことはできません。

console.log(obj.c.c1); // 'c1'
console.log(objA.c.c1); // 'c1'

実装方法4: 再帰を使用する

ディープコピーやマルチレイヤーディープコピーを実現したい場合は、再帰ループコピーを使用できます。

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

const ReCopy = 関数 (パラメータ) {
        ターゲットを null にします。
        isObject = paramter.constructor === Object とします。
        isArray = paramter.constructor === Array とします。
        if (isObject || isArray) {
            ターゲット = Array.isArray(パラメータ) ? [] : {};
            for (let i in パラメータ) {
                ターゲット[i] = ReCopy(パラメータ[i]);
            }
        } それ以外 {
            ターゲット = パラメータ;
        }
        ターゲットを返します。
    }

objA = ReCopy(obj); とします。
objA.c.c1 = 'c1';

コンソールログ(obj.c.c1); // 10
console.log(objA.c.c1); // 'c1'

5. ラダッシュディープコピー

lodashディープ コピーは、より専門的なディープ コピー メソッドです。

lodashをインストールする

まず初期化し、 package.jsonファイルを生成してから、次のコマンドを使用してインストールします。

npm i -S lodash

lodash をインポートする

var _ = require('lodash');

lodashの使用

obj = {
    a:1、
    b:2、
    c:{
        c1:10,
        2:20 ...
    }
}

objA = _.cloneDeep(obj); とします。
objA.c.c1 = 'c1'; 

コンソールログ(obj.c.c1); // 10
console.log(objA.c.c1); // 'c1'

これで、JS のディープ コピーとシャロー コピーに関する詳細な記事は終了です。JS のディープ コピーとシャロー コピーに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript のコピーオブジェクトと Object.assign メソッドではディープコピーを実現できません
  • JavaScript のディープコピーの詳細な説明と例の分析
  • Javascript のディープコピーに関する簡単な説明
  • Json オブジェクトを介してディープコピーを実現する方法の改良版
  • JavaScript オブジェクトのディープコピーとシャローコピーの詳細な説明

<<:  DockerはRedisを起動し、パスワードを設定します

>>:  MySQLアカウントのパスワード変更方法(概要)

推薦する

Linux または Android でファイル システムを追加する属性インターフェイスを解析する方法

最初のもの: 1. 主要なヘッダーファイルを追加します。 #include <linux/of...

チェックボックスの選択またはキャンセルを実装するJavaScript

この記事では、すべてのチェックボックスを選択または解除するためのJavaScriptの具体的なコード...

ドラッグ可能なログインボックスを実現するネイティブJS

この記事では、ネイティブ JS で実装されたドラッグ可能なログイン ボックスを紹介します。その効果は...

2つのVirtualBox仮想ネットワークをブリッジするLinuxブリッジメソッドの手順

この記事は、この時期の「ピーターから奪ってポールに払う」という仕事のスタイルに対する私の不満から生ま...

MySQL InnoDB の重要なコンポーネントの概要

Innodbには以下のコンポーネントが含まれています1. innodb_buffer_pool:これ...

Linux で ffmpeg をインストールするための詳細なチュートリアル

1. CentOS Linuxにffmpegをインストールする1.ダウンロードして解凍する http...

sqlalchemy に基づいて MySQL で追加、削除、変更、クエリ操作を実装する

需要シナリオ:上司は、クロ​​ーラーを使用してMySQLデータベースにデータを書き込んだり更新したり...

セマンティックウェブページ XHTML セマンティックマークアップ

構造とプレゼンテーションを分離するもう 1 つの重要な側面は、セマンティック マークアップを使用して...

Nginxポーリングアルゴリズムの基本的な実装方法の詳細な説明

ポーリングアルゴリズムの紹介多くの人が職場で nginx を使用しており、その設定に精通しています。...

Windows で IP アドレスを指定してサーバーへのリモート アクセスを設定する方法

当社には、外部ネットワークからの干渉を受けることが多いサーバーが多数あります。侵入者はポート 338...

Dockerイメージの作成とプロジェクト全体のワンクリックパッケージングとデプロイ

一般的な Dockerfile 命令の紹介命令説明するから新しいイメージが構築される基となるイメージ...

Nginxは特定のページへのIPアクセスを制限します

1.すべてのIPアドレスが3つのページa1.htm、a2.htm、a3.htmにアクセスするのを禁止...

MySQL 5.7.17 winx64 のインストールと設定のチュートリアル

今日、MySQL データベースをコンピューターに再度インストールしました。システムを再インストールす...

Reactのようなフレームワークをゼロから作成する

最近、インターネットで「Build your own React」という記事を見ました。著者は、シン...

MySQL に大量のデータを挿入するときに重複データを除外する方法

目次1. 問題を発見する2.重複したデータを残さずにすべて削除する3. 削除テーブルから重複データを...