È importante capire cos'è il file = fa e cosa non fa operatore in JavaScript.
L' =operatore non fa una copia dei dati.
L' =operatore crea un nuovo riferimento allo stesso dati.
Dopo aver eseguito il codice originale:
var a = $('#some_hidden_var').val(),
b = a;
ae bora sono due nomi diversi per lo stesso oggetto .
Qualsiasi modifica apportata al contenuto di questo oggetto verrà visualizzata in modo identico indipendentemente dal fatto che lo si faccia riferimento tramite la avariabile o ilb variabile. Sono lo stesso oggetto.
Quindi, quando in seguito proverai a "ripristinare" bl' aoggetto originale con questo codice:
b = a;
Il codice in realtà non fa nulla , perché ae bsono la stessa identica cosa. Il codice è lo stesso come se avessi scritto:
b = b;
che ovviamente non farà nulla.
Perché il tuo nuovo codice funziona?
b = { key1: a.key1, key2: a.key2 };
Qui stai creando un oggetto nuovo di zecca con l' {...}oggetto letterale. Questo nuovo oggetto non è lo stesso del tuo vecchio oggetto. Quindi ora stai impostandob come riferimento a questo nuovo oggetto, che fa quello che vuoi.
Per gestire qualsiasi oggetto arbitrario, puoi utilizzare una funzione di clonazione di oggetti come quella elencata nella risposta di Armand, o poiché stai usando jQuery usa semplicemente la $.extend()funzione . Questa funzione creerà una copia superficiale o una copia completa di un oggetto. (Non confonderlo con il $().clone()metodo che serve per copiare elementi DOM, non oggetti.)
Per una copia superficiale:
b = $.extend( {}, a );
O una copia completa:
b = $.extend( true, {}, a );
Qual è la differenza tra una copia superficiale e una copia profonda? Una copia superficiale è simile al codice che crea un nuovo oggetto con un oggetto letterale. Crea un nuovo oggetto di primo livello contenente riferimenti alle stesse proprietà dell'oggetto originale.
Se il tuo oggetto contiene solo tipi primitivi come numeri e stringhe, una copia completa e una copia superficiale faranno esattamente la stessa cosa. Ma se il tuo oggetto contiene altri oggetti o array annidati al suo interno, una copia superficiale non copia quegli oggetti annidati, ma semplicemente crea riferimenti ad essi. Quindi potresti avere lo stesso problema con gli oggetti nidificati che avevi con il tuo oggetto di primo livello. Ad esempio, dato questo oggetto:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
Se esegui una copia superficiale di quell'oggetto, la xproprietà del tuo nuovo oggetto è lo stesso xoggetto dell'originale:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
Ora i tuoi oggetti avranno questo aspetto:
// 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
}
};
Puoi evitarlo con una copia completa. La copia profonda ricorre in ogni oggetto e array annidato (e Data nel codice di Armand) per fare copie di quegli oggetti nello stesso modo in cui ha fatto una copia dell'oggetto di primo livello. Quindi il cambiamento copy.x.ynon avrebbe effettoobj.x.y .
Risposta breve: in caso di dubbio, probabilmente vuoi una copia completa.
astato impostato da.val()presumo che sia JSON (una stringa), non un oggetto, è vero? UsiJSON.parse(a)ad un certo punto per ottenere un oggetto reale?