Kāds ir efektīvākais veids, kā klonēt JavaScript objektu? Esmu redzējis, ka tiek izmantots obj = eval(uneval(o));
, bet tas ir nestandarta un to atbalsta tikai Firefox.
Es'esmu darījis tādas lietas kā obj = JSON.parse(JSON.stringify(o));
, bet šaubos par efektivitāti.
Es'esmu redzējis arī rekursīvas kopēšanas funkcijas ar dažādiem trūkumiem.
Es'esmu pārsteigts, ka nav kanoniska risinājuma.
To sauc par "strukturētu klonēšanu", eksperimentāli tas darbojas Node 11 un jaunākajās versijās un, cerams, tiks ieviests pārlūkprogrammās. Sīkāku informāciju sk. šajā atbildē.
Ja objektā neizmantojat Date
, funkcijas, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, retākus masīvus, tipveida masīvus vai citus sarežģītus tipus, ļoti vienkārša viena līnija, lai dziļi klonētu objektu, ir:
Klonēšana: 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()
Sk. Corban's atbildi, lai uzzinātu etalonus.
Tā kā objektu klonēšana nav triviāla (sarežģīti tipi, apļveida atsauces, funkcijas utt.), lielākā daļa lielāko bibliotēku piedāvā funkciju objektu klonēšanai. Neizgudrojiet velosipēdu no jauna - ja jau izmantojat kādu bibliotēku, pārbaudiet, vai tajā ir objektu klonēšanas funkcija. Piemēram,
cloneDeep
; var importēt atsevišķi, izmantojot moduli lodash.clonedeep, un, iespējams, tā ir labākā izvēle, ja vēl neizmantojat bibliotēku, kas nodrošina dziļas klonēšanas funkciju.angular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
klonē tikai DOM elementus.Pilnīguma labad jāatzīmē, ka ES6 piedāvā divus seklās kopēšanas mehānismus: Object.assign()
un spread operators.
Ja nav iebūvēta neviena, varat izmēģināt:
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;
}