ホームページ ウェブフロントエンド jsチュートリアル JavaScriptディープコピー(deepClone)の詳細説明

JavaScriptディープコピー(deepClone)の詳細説明

Jan 03, 2017 pm 03:59 PM

JavaScript ディープ コピーは、初心者だけでなく経験豊富な開発者でもよく遭遇する問題であり、JavaScript ディープ コピーをよく理解できません。

ディープコピー(deepClone)?

深いコピーの反対は浅いコピーです。多くの初心者はこの概念に触れると非常に混乱します。

ディープコピーを使用する理由は何ですか?

多くの場合、変数に値を代入し、メモリアドレスに値を代入する必要がありますが、参照値型を代入する場合、メモリ領域を共有するだけなので、代入は以前のものと一貫性が保たれます。価値。 。

具体的な例を見てみましょう

// 给test赋值了一个对象
var test = {
  a: 'a',
  b: 'b'
};
 
// 将test赋值给test2
// 此时test和test2是共享了同一块内存对象,这也就是浅拷贝
var test2 = test;
 
test2.a = 'a2';
 
test.a === 'a2'// 为true
ログイン後にコピー

イラスト:


これで、参照値型データが相互に影響を与える理由を簡単に理解できます。

実装

ディープコピー関数を実装するには、JavaScriptの数値型について話し合う必要があります。

JavaScriptの型を決定する

JavaScriptには次の基本的な型があります

型の説明
unknown未定義の型には、値が1つだけあります。未定義は、変数に値が割り当てられていない場合の値です
null null型も空のオブジェクト参照である null 値が 1 つだけあります
Boolean Boolean には true と false の 2 つの値があります
String テキスト情報を表します
Number 数値情報を表します
Object 関数や関数を含む一連の属性の順序付けされていないコレクションですarray 配列
typeof では判定できません 関数や配列については、ここでは Object.prototype.toString メソッドを使用します。
[デフォルトでは、各オブジェクトは Object から toString() メソッドを継承します。このメソッドがオブジェクト自体またはより上位のプロトタイプの同じ名前のメソッドによってオーバーライド (シャドウ) されていない場合、オブジェクトの toString() が呼び出されます。 ) メソッドは "[オブジェクト タイプ]" を返します。ここでの文字列タイプはオブジェクト タイプを表します][1]

function type(obj) {
  var toString = Object.prototype.toString;
  var map = {
    '[object Boolean]' : 'boolean', 
    '[object Number]'  : 'number', 
    '[object String]'  : 'string', 
    '[object Function]' : 'function', 
    '[object Array]'  : 'array', 
    '[object Date]'   : 'date', 
    '[object RegExp]'  : 'regExp', 
    '[object Undefined]': 'undefined',
    '[object Null]'   : 'null', 
    '[object Object]'  : 'object'
  };
  return map[toString.call(obj)];
}
ログイン後にコピー

deepClone の実装

非参照値タイプの値、直接代入、および参照値タイプの場合(オブジェクト) を再度走査し、再帰的に割り当てる必要があります。

function deepClone(data) {
  var t = type(data), o, i, ni;
   
  if(t === 'array') {
    o = [];
  }else if( t === 'object') {
    o = {};
  }else {
    return data;
  }
   
  if(t === 'array') {
    for (i = 0, ni = data.length; i < ni; i++) {
      o.push(deepClone(data[i]));
    }
    return o;
  }else if( t === &#39;object&#39;) {
    for( i in data) {
      o[i] = deepClone(data[i]);
    }
    return o;
  }
}
ログイン後にコピー

ここで注意すべき点があります。関数の種類について、ここのブロガーは値を直接割り当てるか、メモリ値を共有します。これは、関数が入力値と戻り値を持つ特定の関数を完了することに重点があり、上位レベルのビジネスにとってはビジネス関数を完了することに重点があり、関数を実際にディープ コピーする必要がないためです。

しかし、関数の型をコピーするにはどうすればよいでしょうか?

実際、ブロガーは new を使用して操作することしか考えていませんでしたが、関数は 1 回実行されます。実行結果がどうなるかは想像できません。 o(╯□╰)o!他に良いアイデアはまだないので、皆さんのご指導大歓迎です!

この時点で、ディープコピーはほぼ実装されていますが、シャローコピーはまだ実装されていないと思う人はいますか?

浅いコピーですか?

シャローコピーの場合は、共通メモリ領域を操作するだけと理解できます!ここには危険が潜んでいるでしょう! (.﹏.*)

この共有データを制御せずに直接操作すると、頻繁にデータ異常が発生し、他の部分によってデータが変更されてしまいます。したがって、データ ソースを直接操作するのではなく、データ ソースでデータに対して CURD 操作を実行するためのいくつかのメソッドをカプセル化する必要があります。

おそらくここでほぼ完成ですが、フロントエンドとしては JavaScript 自体だけでなく、DOM やブラウザなども考慮する必要があります。

要素の型

次のコードを見てください。何が返されるでしょうか?

Object.prototype.toString.call(document.getElementsByTagName('div')[0])

答えは、[object HTMLDivElement]です

時々、dom 要素を保存して、誤って深いコピーを作成してしまうことがあります。 Element 要素に対する判断力が欠けています。 Element要素を判定するにはinstanceofを使用して判定します。異なるタグの場合、tostring は異なるタグに対応するコンストラクターを返すためです。

function type(obj) {
  var toString = Object.prototype.toString;
  var map = {
    &#39;[object Boolean]&#39; : &#39;boolean&#39;, 
    &#39;[object Number]&#39;  : &#39;number&#39;, 
    &#39;[object String]&#39;  : &#39;string&#39;, 
    &#39;[object Function]&#39; : &#39;function&#39;, 
    &#39;[object Array]&#39;  : &#39;array&#39;, 
    &#39;[object Date]&#39;   : &#39;date&#39;, 
    &#39;[object RegExp]&#39;  : &#39;regExp&#39;, 
    &#39;[object Undefined]&#39;: &#39;undefined&#39;,
    &#39;[object Null]&#39;   : &#39;null&#39;, 
    &#39;[object Object]&#39;  : &#39;object&#39;
  };
  if(obj instanceof Element) {
    return &#39;element&#39;;
  }
  return map[toString.call(obj)];
}
ログイン後にコピー

最初に JSON.stringify を渡し、次に JSON.parse を渡してディープ コピーを実現します。ただし、データ型は基本的な数値型のみをサポートします。

var obj = {
  a: &#39;a&#39;, 
  b: function(){console.log(&#39;b&#39;)}
}
 
//在JSON.stringify的时候就会把function给过滤了。
 
JSON.stringify(obj)// "{"a":"a"}"
ログイン後にコピー

概要

ディープコピーの概要とディープコピーの実装方法について説明します。さまざまなシナリオで、ビジネス シナリオに基づいてディープ コピーを使用する必要があるかどうかを判断する必要があります。

JavaScript ディープコピー (deepClone) 関連記事の詳細については、PHP 中国語 Web サイトに注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptの文字列文字を交換します JavaScriptの文字列文字を交換します Mar 11, 2025 am 12:07 AM

JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

jQueryのパフォーマンスを即座に増やす10の方法 jQueryのパフォーマンスを即座に増やす10の方法 Mar 11, 2025 am 12:15 AM

この記事では、スクリプトのパフォーマンスを大幅に向上させるための10の簡単な手順の概要を説明します。 これらの手法は簡単で、すべてのスキルレベルに適用できます。 更新の維持:NPMのようなパッケージマネージャーを使用して、Viteなどのバンドラーを使用して確認してください

後遺症とMySQLを使用したパスポートを使用します 後遺症とMySQLを使用したパスポートを使用します Mar 11, 2025 am 11:04 AM

Sequelizeは、約束ベースのnode.js ormです。 PostgreSQL、MySQL、MariadB、SQLite、およびMSSQLで使用できます。このチュートリアルでは、Webアプリのユーザー向けに認証を実装します。また、人気のある認証ミドルであるPassportを使用します

シンプルなjQueryスライダーを構築する方法 シンプルなjQueryスライダーを構築する方法 Mar 11, 2025 am 12:19 AM

この記事では、jQueryライブラリを使用してシンプルな画像カルーセルを作成するように導きます。 jQuery上に構築されたBXSLiderライブラリを使用し、カルーセルをセットアップするために多くの構成オプションを提供します。 今日、絵のカルーセルはウェブサイトで必須の機能になっています - 1つの写真は千の言葉よりも優れています! 画像カルーセルを使用することを決定した後、次の質問はそれを作成する方法です。まず、高品質の高解像度の写真を収集する必要があります。 次に、HTMLとJavaScriptコードを使用して画像カルーセルを作成する必要があります。ウェブ上には、さまざまな方法でカルーセルを作成するのに役立つ多くのライブラリがあります。オープンソースBXSLiderライブラリを使用します。 BXSLiderライブラリはレスポンシブデザインをサポートしているため、このライブラリで構築されたカルーセルは任意のものに適合させることができます

See all articles