Es importante comprender qué =hace y qué no hace el operador en JavaScript.
El =operador no realiza una copia de los datos.
El =operador crea una nueva referencia a los mismos datos.
Después de ejecutar su código original:
var a = $('#some_hidden_var').val(),
b = a;
ay bahora son dos nombres diferentes para el mismo objeto .
Cualquier cambio que realice en el contenido de este objeto se verá de manera idéntica ya sea que haga referencia a él a través de la avariable o la bvariable. Son el mismo objeto.
Entonces, cuando más tarde intente "volver" bal aobjeto original con este código:
b = a;
El código en realidad no hace nada en absoluto , porque ay bson exactamente lo mismo. El código es el mismo que si hubiera escrito:
b = b;
que obviamente no hará nada.
¿Por qué funciona tu nuevo código?
b = { key1: a.key1, key2: a.key2 };
Aquí está creando un objeto nuevo con el {...}objeto literal. Este nuevo objeto no es el mismo que su antiguo objeto. Así que ahora estás configurandob como referencia a este nuevo objeto, que hace lo que quiere.
Para manejar cualquier objeto arbitrario, puede usar una función de clonación de objetos como la que se enumera en la respuesta de Armand, o como está usando jQuery, simplemente use la $.extend()función . Esta función hará una copia superficial o una copia profunda de un objeto. (No confunda esto con el $().clone()método que es para copiar elementos DOM, no objetos).
Para una copia superficial:
b = $.extend( {}, a );
O una copia profunda:
b = $.extend( true, {}, a );
¿Cuál es la diferencia entre una copia superficial y una profunda? Una copia superficial es similar a su código que crea un nuevo objeto con un objeto literal. Crea un nuevo objeto de nivel superior que contiene referencias a las mismas propiedades que el objeto original.
Si su objeto contiene solo tipos primitivos como números y cadenas, una copia profunda y una copia superficial harán exactamente lo mismo. Pero si su objeto contiene otros objetos o matrices anidadas dentro de él, entonces una copia superficial no copia esos objetos anidados, simplemente crea referencias a ellos. Entonces, podría tener el mismo problema con los objetos anidados que tenía con su objeto de nivel superior. Por ejemplo, dado este objeto:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
Si hace una copia superficial de ese objeto, entonces la xpropiedad de su nuevo objeto es el mismo xobjeto del original:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
Ahora sus objetos se verán así:
// copy looks as expected
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
// But changing copy.x.y also changed obj.x.y!
var obj = {
w: 123, // changing copy.w didn't affect obj.w
x: {
y: 654, // changing copy.x.y also changed obj.x.y
z: 789
}
};
Puede evitar esto con una copia profunda. La copia profunda se repite en cada objeto y matriz anidados (y Fecha en el código de Armand) para hacer copias de esos objetos de la misma manera que hizo una copia del objeto de nivel superior. Así que cambiar copy.x.yno afectaría obj.x.y.
Respuesta corta: en caso de duda, probablemente desee una copia detallada.
ase configuró desde.val(), supongo que es JSON (una cadena), no un objeto, ¿es así? ¿UsasJSON.parse(a)en algún momento para obtener un objeto real?