Mi a leghatékonyabb módja egy JavaScript objektum klónozásának? Láttam, hogy az obj = eval(uneval(o));
-t használják, de ez nem szabványos, és csak a Firefox támogatja.
I've done things like obj = JSON.parse(JSON.stringify(o));
, de megkérdőjelezem a hatékonyságot. <br/br/><br/br/> Láttam rekurzív másoló függvényeket is különböző hibákkal.
<br/br />
I'm meglepő, hogy nincs kanonikus megoldás.
Ezt "strukturált klónozásnak" hívják, kísérletképpen működik a Node 11-ben és később, és remélhetőleg a böngészőkben is landol. További részletekért lásd ez a válasz.
Ha nem használsz Date
s, függvényeket, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays vagy más összetett típusokat az objektumodon belül, egy nagyon egyszerű egysoros egy objektum mélyklónozásához:
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()
Lásd Corban's answer a benchmarkokat.
Mivel az objektumok klónozása nem triviális (összetett típusok, körkörös hivatkozások, függvények stb.), a legtöbb nagy könyvtár biztosít funkciót az objektumok klónozására. Ne találd fel újra a kereket - ha már használsz egy könyvtárat, ellenőrizd, hogy van-e benne objektumklónozó funkció. Például,
cloneDeep
; külön importálható a lodash.clonedeep modulon keresztül, és valószínűleg a legjobb választás, ha még nem használsz olyan könyvtárat, amely mély klónozási funkciót biztosít.angular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
csak DOM elemeket klónoz.A teljesség kedvéért jegyezzük meg, hogy az ES6 két sekély másolási mechanizmust kínál: Object.assign()
és a spread operator.
Ha nem lenne beépített, megpróbálhatná:
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;
}
function clone(obj)
{ var clone = {};
clone.prototype = obj.prototype;
for (property in obj) clone[property] = obj[property];
return clone;
}