Hier ist eine Version der obigen Antwort von ConroyP, die auch funktioniert, wenn der Konstruktor erforderliche Parameter hat:
//If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
object_create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
}
function deepCopy(obj) {
if(obj == null || typeof(obj) !== 'object'){
return obj;
}
//make sure the returned object has the same prototype as the original
var ret = object_create(obj.constructor.prototype);
for(var key in obj){
ret[key] = deepCopy(obj[key]);
}
return ret;
}
Diese Funktion ist auch in meinem simpleoo Bibliothek.
編集する。
Hier ist eine robustere Version (dank Justin McCandless unterstützt diese nun auch zyklische Referenzen):
/**
* Deep copy an object (make copies of all its object properties, sub-properties, etc.)
* An improved version of http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
* that doesn't break if the constructor has required parameters
*
* It also borrows some code from http://stackoverflow.com/a/11621004/560114
*/
function deepCopy(src, /* INTERNAL */ _visited, _copiesVisited) {
if(src === null || typeof(src) !== 'object'){
return src;
}
//Honor native/custom clone methods
if(typeof src.clone == 'function'){
return src.clone(true);
}
//Special cases:
//Date
if(src instanceof Date){
return new Date(src.getTime());
}
//RegExp
if(src instanceof RegExp){
return new RegExp(src);
}
//DOM Element
if(src.nodeType && typeof src.cloneNode == 'function'){
return src.cloneNode(true);
}
// Initialize the visited objects arrays if needed.
// This is used to detect cyclic references.
if (_visited === undefined){
_visited = [];
_copiesVisited = [];
}
// Check if this object has already been visited
var i, len = _visited.length;
for (i = 0; i < len; i++) {
// If so, get the copy we already made
if (src === _visited[i]) {
return _copiesVisited[i];
}
}
//Array
if (Object.prototype.toString.call(src) == '[object Array]') {
//[].slice() by itself would soft clone
var ret = src.slice();
//add it to the visited array
_visited.push(src);
_copiesVisited.push(ret);
var i = ret.length;
while (i--) {
ret[i] = deepCopy(ret[i], _visited, _copiesVisited);
}
return ret;
}
//If we've reached here, we have a regular object
//make sure the returned object has the same prototype as the original
var proto = (Object.getPrototypeOf ? Object.getPrototypeOf(src): src.__proto__);
if (!proto) {
proto = src.constructor.prototype; //this line would probably only be reached by very old browsers
}
var dest = object_create(proto);
//add this object to the visited array
_visited.push(src);
_copiesVisited.push(dest);
for (var key in src) {
//Note: this does NOT preserve ES5 property attributes like 'writable', 'enumerable', etc.
//For an example of how this could be modified to do so, see the singleMixin() function
dest[key] = deepCopy(src[key], _visited, _copiesVisited);
}
return dest;
}
//If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
object_create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
}
566 Stimmen
Eval ist nicht böse. Schlechtes Benutzen von Eval schon. Wenn Sie Angst vor seinen Nebenwirkungen haben, verwenden Sie es falsch. Die Nebenwirkungen, die Sie fürchten, sind der Grund, warum Sie es verwenden. Hat eigentlich irgendjemand Ihre Frage beantwortet?
15 Stimmen
Das Klonen von Objekten ist eine knifflige Angelegenheit, insbesondere bei benutzerdefinierten Objekten beliebiger Sammlungen. Wahrscheinlich gibt es deshalb keine fertige Methode, dies zu tun.
12 Stimmen
eval()
ist im Allgemeinen eine schlechte Idee, weil viele Javascript-Engine-Optimierer abschalten müssen, wenn sie mit Variablen arbeiten, die übereval
. Nur miteval()
in Ihrem Code kann zu einer schlechteren Leistung führen.1 Stimmen
Hier ist ein Leistungsvergleich zwischen den gängigsten Arten von Klonobjekten: jsben.ch/#/t917Z
12 Stimmen
Beachten Sie, dass
JSON
Methode werden alle Javascript-Typen, die keine Entsprechung in JSON haben, verloren. Zum Beispiel:JSON.parse(JSON.stringify({a:null,b:NaN,c:Infinity,d:undefined,e:function(){},f:Number,g:false}))
erzeugt{a: null, b: null, c: null, g: false}
0 Stimmen
Die React-Gemeinschaft hat Folgendes eingeführt Unveränderlichkeits-Hilfsmittel