2010-09-22 14 views
16

Duplicar posible:
How to clone js object?¿Clonación de un objeto JavaScript?

Ésta es otra manera de crear un objeto de javascript (usando notación literal de objetos en lugar de la función):

user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

¿Hay una manera para clonar este objeto o es un singleton?

+3

Objeto JavaScript! = Objeto JSON. El ejemplo que proporcionó es un literal de objeto de JavaScript; Actualicé tu publicación en consecuencia. –

+0

¡buena pregunta! Siempre pienso que usuario2 = usuario hará una copia, pero no lo haga. – Topera

+1

La 'respuesta' más corta: sí y sí. ;) –

Respuesta

26

Prueba esto:

var clone = (function(){ 
    return function (obj) { Clone.prototype=obj; return new Clone() }; 
    function Clone(){} 
}()); 

Esto es lo que está pasando.

  • Clone es un constructor ficticio.
  • Asignamos el objeto que queremos clonar al prototipo del constructor Clon.
  • Llamamos clonar usando 'nuevo', por lo que el objeto construido tiene el objeto original como prototipo del constructor aka (no estándar) __proto__.

El objeto clonado compartirá todas las propiedades del objeto original sin realizar copias de nada. Si a las propiedades del objeto clonado se les asignan nuevos valores, no interferirán con el objeto original. Y no se requiere alteración de integradas.

Tenga en cuenta que una propiedad de objeto del objeto recién creado se referirá al mismo objeto que la propiedad del mismo nombre del objeto clonado. La asignación de un nuevo valor a una propiedad del clon no interferirá con el original, pero la asignación de valores a las propiedades del objeto del clon sí lo hará.


probar este en cromo o firebug consola:

var user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

var clonedUser = clone(user); 

console.dir(clonedUser); 

Una explicación detallada de esta técnica de clonación se puede encontrar here.

+2

'user = {name:" ", email:" ", obj: {a:" A "}}; clonedUser = clone (usuario); ',' clonedUser.obj.a = "B"; 'encontrarás' user.obj.a == "B" ' – vol7ron

+0

Esto se ve muy similar a la respuesta de Chris J también. – vol7ron

+0

vol7ron: sí, porque user.obj y clonedUser.obj hacen referencia al mismo objeto. La asignación de un nuevo valor a la propiedad 'obj' de newUser no mostrará este comportamiento. La solicitud era para un clon, no una copia, y no una copia profunda. Ver el enlace al final de mi respuesta. –

2

La mayoría de los frameworks de javascript tienen un buen soporte para la clonación de objetos.

var a= {'key':'value'}; 
var b= jQuery.extend(true, {}, a); 
+0

De acuerdo: underscorejs también tiene un método de clonación http://underscorejs.org/#clone – dreftymac

10

Puede utilizar JSON objeto (presente en los navegadores modernos):

var user = {name: "Foo", email: "[email protected]" } 
var user2 = JSON.parse(JSON.stringify(user)) 

user2.name = "Bar"; 
alert(user.name + " " + user2.name); // Foo Bar 

Véase en jsfiddle.


EDITAR

Si necesita esta en navegadores antiguos, ver http://www.json.org/js.html.

+1

hmm ... no voy a downvote you pero esto es tonto, en mi opinión. En primer lugar, si va a utilizar JSON, deberá incluir json2.js en su página porque todavía hay navegadores actuales sin json nativo y habrá en común aquellos que no estén actualizados durante un tiempo. Escriba o solicite una extensión de implementación o incluya una biblioteca que tenga una. –

+0

Solo estoy dando otra forma de hacer esto. Si un sitio ya tiene json2.js, funciona. – Topera

+1

Si un objeto tiene tanto 'propiedades' como' métodos', entonces mi amigo, usando este estilo JSON, 'methods' no ** están clonados ** –

4

me gusta usar esto:

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     var F = function() {}; 
     F.prototype = o; 
    return new F(); 
    }; 
} 

entonces cualquier objeto Quiero clonar se puede hacer como:

user = { 
    name: "Foo", 
    email: "[email protected]" 
}; 
var user2 = Object.create(user); 

Como se muestra en (o similares a) de JavaScript las partes buenas

+1

No deberías hacer esto; ver [respuesta de Kangax] (http://stackoverflow.com/questions/3075308/what-modernizer-scripts-exist-for-the-new-ecmascript-5-functions/3075818#3075818) –

+2

@Marcel Gracias por señalar eso fuera. Dejaré mi respuesta tal como está y recomendaré la explicación de Kangax como una buena lectura. –

+0

@ Marcel/Chris +1; La respuesta de Kangax es solo que crear no toma dos propiedades en todas partes. Mi sensación es que si todos usaran este método, obligaría a los vendedores a cumplir con los estándares. No usé FF inicialmente porque no mostraba todo correctamente, ahora la web se volvió más inteligente y FF hizo modificaciones para funcionar mejor en el modo peculiar. Lo mismo ocurrirá si los programadores se limitan a los estándares y presionan a los navegadores que los aceptan. – vol7ron

0
Object.prototype.clone = function clone(obj) { 
          obj = obj || this; 
          var new_obj = {}; 

          for(var p in obj) { 
          if (obj.hasOwnProperty(p)) { 
           if(obj[p] !== null && typeof(obj[p]) === "object") { 
           new_obj[p] = clone(obj[p]); 
           } 
           else { 
           new_obj[p] = obj[p]; 
           } 
          } 
          } 

          return new_obj; 
         }; 


/* Example */ 
var foo = { 
    name: "Foo" 
    , email: "[email protected]" 
    , obj: {a:"A",b:"B"} 
}; 

var bar = foo.clone(); 
bar.name = "Bar"; 
bar.obj.b = "C"; 


// foo and bar should have a different 'name' 
// foo and bar should retain the same email 
// foo and bar should have different values for <foo/bar>['obj']['b'] 
// foo and bar should have the same values for <foo/bar>['obj']['a'] 
console.dir(foo); 
console.dir(bar); 
+3

no no no ... nunca te metas con Object.prototype, vas a romper todo: P –

+2

que es incorrecto, a menos que seas uno de los drones que usan 'JQuery', entonces nunca te metas con nada y olvídate de cómo hacerlo cualquier cosa. – vol7ron

+2

No te enojes. Generalmente evito jQuery. Sin embargo, dos cosas ... 1, esto no es un clon, es una copia. El nombre 'clonación' está asociado con este tipo de técnica: http://oranlooney.com/functional-javascript/ –