JavaScriptのオブジェクトをクローンする最も効率的な方法は何ですか?obj = eval(uneval(o));が使われているのを見たことがありますが、[これは非標準で、Firefoxでしかサポートされていません][1].<br/><br/>私は、
obj = JSON.parse(JSON.stringify(o));のようなことをしましたが、効率に疑問があります。parse(JSON.stringify(o));
のようなことはやったことがありますが、効率性に疑問があります。
また、様々な欠陥のある再帰的なコピー関数を見たことがあります。
。
正統な解決策が存在しないことに驚きました。
これは「構造化クローニング」と呼ばれ、Node 11以降で実験的に動作しており、うまくいけばブラウザにも搭載されるでしょう。詳細はこの回答を参照してください。
Dates, 関数,
undefined,
Infinity`, RegExps, Map, Set, Blob, FileList, ImageDatas, sparse Arrays, Typed Arrays などの複雑な型をオブジェクト内で使用していない場合は、非常にシンプルな方法でオブジェクトのディープクローンを作成することができます。
JSON.parse(JSON.stringify(object))
です。
<! -- begin snippet: js hide: false console: true babel: false -->
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()
<! -- スニペットの終了 -->
ベンチマークはCorban's answerを参照してください。
オブジェクトの複製は簡単ではないので(複雑な型、循環参照、関数など)、ほとんどの主要なライブラリはオブジェクトを複製する関数を提供しています。Don't reinvent the wheel - 既にライブラリを使用している場合は、そのライブラリにオブジェクトクローニング機能があるかどうかを確認してください。例えば、以下のようなものです。
cloneDeep
; ldash.clonedeepモジュールを介して別途インポートすることができ、ディープクローニング機能を提供するライブラリをまだ使用していない場合は、おそらく最良の選択です。angular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
はDOM要素をクローンするだけです。念のため、ES6には2つの浅いコピーメカニズムがあることに注意してください。Object.assign()`とspread operatorです。
もし、内蔵されていなかったら、試してみてください。
function clone(obj) {
if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
return obj;
if (obj instanceof Date)
var temp = new obj.constructor(); //or new Date(obj);
else
var temp = obj.constructor();
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj['isActiveClone'] = null;
temp[key] = clone(obj[key]);
delete obj['isActiveClone'];
}
}
return temp;
}