1. ホーム
  2. javascript

[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?

2022-03-16 23:36:51

質問

JavaScriptのオブジェクトをクローンする最も効率的な方法は何ですか?私が見たのは obj = eval(uneval(o)); が使用されていますが これは非標準であり、Firefoxでのみサポートされています。 .
のようなことをしたことがあります。 obj = JSON.parse(JSON.stringify(o)); が、効率に疑問がある。
また、様々な欠陥のある再帰的コピー関数も見たことがあります。
標準的なソリューションが存在しないのが不思議なくらいです。

どのように解決するのですか?

ネイティブディープクローニング

というJS規格ができました。 構造化クローニング" Node 11以降で実験的に動作し、ブラウザに搭載され、さらに 既存システム用ポリフィル .

structuredClone(value)

必要であれば、まずポリフィルを読み込みます。

import structuredClone from '@ungap/structured-clone';

参照 この回答 をご覧ください。

過去の回答

データ損失を伴う高速クローニング - JSON.parse/stringify

を使用しない場合 Date の、関数です。 undefined , Infinity RegExps、マップ、セット、ブロブ、ファイルリスト、イメージデータ、疎な配列、型付き配列など、オブジェクト内の複雑な型をディープクローンするには、非常にシンプルなワンライナーを使用します。

JSON.parse(JSON.stringify(object))

const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
  re: /.*/,  // lost
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString()

参照 コーバンの回答 はベンチマークを参照してください。

ライブラリを利用した信頼性の高いクローン作成

オブジェクトのクローン作成は簡単ではない(複雑な型、循環参照、関数など)ため、ほとんどの主要なライブラリはオブジェクトのクローン作成機能を提供しています。 車輪の再発明をしない - すでに使っているライブラリがあれば、オブジェクトクローン機能があるかどうか確認してください。例えば

  • ロダッシュ cloneDeep を使用して個別にインポートすることができます。 lodash.clonedeep モジュールは、ディープクローニング機能を提供するライブラリをまだ使用していない場合には、おそらく最良の選択でしょう。
  • AngularJS angular.copy
  • jQuery jQuery.extend(true, { }, oldObject) ; .clone() DOM 要素のクローンを作成するだけです。
  • 単なるライブラリ just-clone 依存性のないnpmモジュールのライブラリの一部で、ただ一つのことを行うだけです。 あらゆる場面で罪悪感のないユーティリティを提供します。

ES6 ( 浅い コピー)

完全を期すために、ES6には2つの浅いコピーメカニズムがあることに注意してください。 Object.assign() スプレッド構文 . これは、すべての列挙可能な自身のプロパティの値を、あるオブジェクトから別のオブジェクトにコピーするものです。例えば

var A1 = {a: "2"};
var A2 = Object.assign({}, A1);
var A3 = {...A1};  // Spread Syntax