Bir JavaScript nesnesini klonlamanın en etkili yolu nedir? obj = eval(uneval(o));kullanıldığını gördüm, ancak [bu standart değil ve yalnızca Firefox tarafından destekleniyor][1].<br/><br/>
obj = JSON gibi şeyler yaptım.parse(JSON.stringify(o));` gibi şeyler yaptım ancak verimliliği sorguladım.
Ayrıca çeşitli kusurları olan özyinelemeli kopyalama işlevleri de gördüm.
Kanonik bir çözüm bulunmamasına şaşırdım.
Buna "structured cloning" deniyor, Node 11 ve sonrasında deneysel olarak çalışıyor ve umarım tarayıcılara da gelir. Daha fazla ayrıntı için bu yanıta bakın.
Nesnenizde Date
, fonksiyonlar, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays veya diğer karmaşık türleri kullanmıyorsanız, bir nesneyi derinlemesine klonlamak için çok basit bir astar vardır:
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()
Kıyaslamalar için Corban'ın cevabına bakınız.
Nesneleri klonlamak önemsiz olmadığından (karmaşık tipler, dairesel referanslar, fonksiyon vb.), çoğu büyük kütüphane nesneleri klonlamak için fonksiyon sağlar. Tekerleği yeniden icat etmeyin - zaten bir kütüphane kullanıyorsanız, nesne klonlama işlevine sahip olup olmadığını kontrol edin. Örneğin,
cloneDeep
; lodash.clonedeep modülü aracılığıyla ayrı olarak içe aktarılabilir ve halihazırda derin bir klonlama işlevi sağlayan bir kütüphane kullanmıyorsanız muhtemelen en iyi seçimdirangular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
yalnızca DOM öğelerini klonlarBütünlük için, ES6'nın iki sığ kopyalama mekanizması sunduğunu unutmayın: Object.assign()
ve spread operator.
Eğer yerleşik bir tane yoksa, deneyebilirsiniz:
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;
}