Nel documento code context che hai ora divulgato, questa tecnica viene utilizzata per fare una copia di un oggetto passato a una funzione in modo che le modifiche a quell'oggetto non modifichino l'originale. Ecco il contesto dal tuo link:
// route reply/error
this.connection.on('message', function(msg) {
var msg = JSON.parse(JSON.stringify(msg));
var handler;
if (msg.type == constants.messageType.methodReturn || msg.type == constants.messageType.error) {
handler = self.cookies[msg.replySerial];
if (msg.type == constants.messageType.methodReturn && msg.body)
msg.body.unshift(null); // first argument - no errors, null
if (handler) {
delete self.cookies[msg.replySerial];
var props = {
connection: self.connection,
bus: self,
message: msg,
signature: msg.signature
};
if (msg.type == constants.messageType.methodReturn)
handler.apply(props, msg.body); // body as array of arguments
else
handler.call(props, msg.body); // body as first argument
}
Nota: la linea in questa clip che contiene msg.body.unshift(null)
. Quello sarebbe modificare l'oggetto originale se questa copia non fosse fatta.
Inoltre, notare che la ridichiarazione di var msg
non sta effettivamente definendo una nuova variabile. Poiché msg
è già definito in questo ambito come argomento della funzione, non è stato rediretto dallo var msg
(questo è tecnicamente un errore nel codice per utilizzare lo var
).
solito la causa di utilizzo di questo tipo di codice è quello di clonare un oggetto (effettuare una copia completa dell'oggetto dove vengono copiate tutte le proprietà incluse oggetti incorporati e array).
var obj = {
list: [1,2,3],
items: [{language: "English", greeting: "hello"},
{language: "Spanish", greeting: "hola"},
{language: "French", greeting: "bonjour"}]
}
// make a completely independent copy of obj
var copy = JSON.parse(JSON.stringify(obj));
copy.items[0].greeting = "Yo";
console.log(obj.items[0].greeting); // "hello"
console.log(copy.items[0].greeting); // "Yo"
Nota: questo funziona solo come una copia completa con oggetti che sono un tipo di oggetto semplice e non hanno proprietà personalizzate che sono funzioni. Inoltre, poiché JSON.stringify()
non supporta riferimenti circolari o riferimenti personali, non è possibile averne uno. E, se hai più riferimenti allo stesso oggetto, ogni riferimento verrà copiato in un nuovo oggetto separato. E, la combinazione di JSON.stringify()
e JSON.parse()
non supporta oggetti diversi da un semplice Object
come RegExp
, Date
o uno qualsiasi dei tuoi oggetti personalizzati (li trasformano in oggetti semplici). Quindi, ci sono alcune limitazioni di questa procedura, ma funziona abbastanza semplicemente per la maggior parte dei casi.
Per Matt (nei commenti), una funzione personalizzata per creare un clone di un oggetto che non supporta i riferimenti circolari e supporta alcuni tipi di oggetti personalizzati può essere visto here.
Nel caso in cui qualcuno stia leggendo questo non si rende conto che assegnare un oggetto a un'altra variabile non crea una copia in Javascript. L'assegnazione in Javascript è come impostare un riferimento a un puntatore allo stesso oggetto.Ogni variabile indica quindi allo stesso oggetto sottostante così modificare l'oggetto sia attraverso variabile finisce modificando lo stesso oggetto in entrambi i casi come questo:
var obj = {
list: [1,2,3],
items: [{language: "English", greeting: "hello"},
{language: "Spanish", greeting: "hola"},
{language: "French", greeting: "bonjour"}]
}
var copy = obj;
// modify copy
copy.items[0].greeting = "Yo";
// both obj and copy refer to the exact same object
console.log(obj.items[0].greeting); // "Yo"
console.log(copy.items[0].greeting); // "Yo"
Pertanto, la necessità occasionale di fare una copia reale profondo di un oggetto.
Vale anche la pena notare che questo non funziona con riferimenti circolari e non conserva più riferimenti allo stesso oggetto (ad esempio, '[a, a]' diventerebbe '[a, b]'). –
@FelixKling - ha aggiunto ulteriori avvertimenti alla risposta. – jfriend00
Per i casi in cui è necessario un clone profondo dell'oggetto, vedere questa risposta: http://stackoverflow.com/a/13333781/560114 –