Mikä on tehokkain tapa kloonata JavaScript-objekti? Olen nähnyt, että obj = eval(uneval(o));
käytetään, mutta se ei ole vakiomuotoinen ja sitä tukee vain Firefox.
Olen tehnyt asioita kuten obj = JSON.parse(JSON.stringify(o));
mutta kyseenalaistan tehokkuuden. <br/br/><br/br/> Olen myös nähnyt rekursiivisia kopiointitoimintoja, joissa on erilaisia puutteita.
<br/br />
Olen yllättynyt, ettei mitään kanonista ratkaisua ole olemassa.
Sitä kutsutaan "rakenteelliseksi kloonaukseksi", se toimii kokeellisesti Node 11:ssä ja uudemmissa, ja toivottavasti se päätyy selaimiin. Katso tämä vastaus lisätietoja.
Jos et käytä Date
, funktioita, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays tai muita monimutkaisia tyyppejä objektissasi, hyvin yksinkertainen one liner objektin syväkloonaukseen on:
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()
Katso Corban's vastaus vertailuarvoja varten.
Koska objektien kloonaus ei ole triviaalia (monimutkaiset tyypit, ympyräviittaukset, funktiot jne.), useimmat suuret kirjastot tarjoavat funktioita objektien kloonaamiseen. Älä keksi pyörää uudelleen - jos käytät jo kirjastoa, tarkista, onko siinä objektien kloonausfunktio. Esim,
cloneDeep
; voidaan tuoda erikseen lodash.clonedeep -moduulin kautta, ja se on luultavasti paras valinta, jos et jo käytä kirjastoa, joka tarjoaa syvän kloonaustoiminnon.angular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
kloonaa vain DOM-elementtejä.Täydellisyyden vuoksi on huomattava, että ES6 tarjoaa kaksi matalaa kopiointimekanismia: Object.assign()
ja spread operator.
Jos sellaista ei ole sisäänrakennettuna, voit kokeilla:
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;
}