Realmente depende de lo que le gustaría clonar. ¿Es este un verdadero objeto JSON o cualquier objeto en JavaScript? Si desea hacer cualquier clon, podría meterse en problemas. ¿Qué problema? Lo explicaré a continuación, pero primero, un ejemplo de código que clona literales de objetos, cualquier primitiva, matriz y nodos DOM.
function clone(item) {
if (!item) { return item; } // null, undefined values check
var types = [ Number, String, Boolean ],
result;
// normalizing primitives if someone did new String('aaa'), or new Number('444');
types.forEach(function(type) {
if (item instanceof type) {
result = type( item );
}
});
if (typeof result == "undefined") {
if (Object.prototype.toString.call( item ) === "[object Array]") {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
} else if (typeof item == "object") {
// testing that this is DOM
if (item.nodeType && typeof item.cloneNode == "function") {
result = item.cloneNode( true );
} else if (!item.prototype) { // check that this is a literal
if (item instanceof Date) {
result = new Date(item);
} else {
// it is an object literal
result = {};
for (var i in item) {
result[i] = clone( item[i] );
}
}
} else {
// depending what you would like here,
// just keep the reference, or create new object
if (false && item.constructor) {
// would not advice to do that, reason? Read below
result = new item.constructor();
} else {
result = item;
}
}
} else {
result = item;
}
}
return result;
}
var copy = clone({
one : {
'one-one' : new String("hello"),
'one-two' : [
"one", "two", true, "four"
]
},
two : document.createElement("div"),
three : [
{
name : "three-one",
number : new Number("100"),
obj : new function() {
this.name = "Object test";
}
}
]
})
Y ahora, hablemos de los problemas que podría tener al comenzar a clonar objetos REALES. Estoy hablando ahora de objetos que creas haciendo algo como
var User = function(){}
var newuser = new User();
Por supuesto, puede clonarlos, no es un problema, cada objeto expone la propiedad del constructor y puede usarlo para clonar objetos, pero no siempre funcionará. También puede hacer algo simple for inen estos objetos, pero va en la misma dirección: problemas. También he incluido la funcionalidad de clonación dentro del código, pero está excluida por if( false )declaración.
Entonces, ¿por qué la clonación puede ser un dolor? Bueno, antes que nada, cada objeto / instancia puede tener algún estado. Nunca puede estar seguro de que sus objetos no tienen, por ejemplo, variables privadas, y si este es el caso, al clonar el objeto, simplemente rompe el estado.
Imagina que no hay un estado, está bien. Entonces todavía tenemos otro problema. La clonación mediante el método "constructor" nos dará otro obstáculo. Es una dependencia de argumentos. Nunca puedes estar seguro de que alguien que creó este objeto no lo hizo, algún tipo de
new User({
bike : someBikeInstance
});
Si este es el caso, no tiene suerte, es probable que someBikeInstance se haya creado en algún contexto y ese contexto no se conoce para el método de clonación.
¿Entonces lo que hay que hacer? Todavía puedes hacerfor in solución y tratar tales objetos como literales de objetos normales, pero tal vez sea una idea no clonar tales objetos en absoluto y simplemente pasar la referencia de este objeto.
Otra solución es: podría establecer una convención de que todos los objetos que deben clonarse deben implementar esta parte por sí mismos y proporcionar el método API adecuado (como cloneObject). Algo que cloneNodeestá haciendo por DOM.
Tú decides.