Tengo el siguiente código (estoy usando la biblioteca jQuery):

var obj = {};
var objstring = '{"one":"one","two":"two","three":"three"}'

// first console output
console.log(objstring);

var jsonobj = $.parseJSON(objstring);

// second console output
console.log(jsonobj);

obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";

// third console output
console.log(jsonobj);

Mi pregunta: cuando hago obj.key = jsonobj y cambio los valores en el nuevo obj.key. ¿Por qué los valores en jsonobj también cambian? ¿Y cómo evitaría eso? (Quiero una nueva "copia" de jsonobj).

Hice este caso de prueba: http://jsfiddle.net/WSgVz/

7
Hans 6 jul. 2011 a las 23:23

5 respuestas

La mejor respuesta

Eso es porque el objeto no se copia. La propiedad obj.key solo contendrá una referencia al objeto, por lo que cuando asigna algo a obj.key.test el efecto es el mismo que asignarlo a jsonobj.test.

Puede utilizar el método jQuery extender para crear una copia:

obj.key = $.extend({}, jsonobj);

Esto copiará los valores en el objeto recién creado ({}).

3
Guffa 6 jul. 2011 a las 19:30

Todos los objetos en JavaScript se copian por referencia, lo que significa:

var x = {};
var y = x;
x.foo = 22; // y.foo also = 22 since y and x are the same object

Si desea obj.key != jsonobj, debe clonar el objeto. Al crear un nuevo objeto:

obj.key = $.parseJSON(objstring);

O usando jQuery para clonar el existente:

obj.key = $.extend({}, jsonobj);
1
Mark Kahn 6 jul. 2011 a las 19:27

Quiero abordar una pequeña parte de lo que está sucediendo aquí, ya que otros lo han hecho muy bien al abordar los problemas más grandes de las referencias de objetos de JavaScript:

// second console output
console.log(jsonobj);

obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";

Este es el resultado de un error documentado de WebKit, que console.log afirma no envíe el objeto al momento de llamar a console.log, sino en algún momento más tarde.

5
Domenic 6 jul. 2011 a las 19:34

Esto se debe a que no se está copiando, solo hay un objeto, que es referenciado por varias variables y propiedades. Cuando haces obj.key = jsonobj, simplemente estás copiando la referencia al mismo objeto.

1
Cameron 6 jul. 2011 a las 19:27

Porque cuando haces obj.key = jsonobj, no hay algún objeto nuevo copiado en obj.key; es solo una referencia a jsonobj que ya existe. Por lo tanto, los cambios en obj.key también cambiarán jsonobj, porque en realidad son lo mismo.

2
sdleihssirhc 6 jul. 2011 a las 19:26