2015-03-20 13 views
5

In un repository ho visto una linea.Metodi di striscia fuori dall'oggetto javascript

var foo = JSON.parse(JSON.stringify(foo)); 

Penso che questo stia cercando di eliminare tutti i metodi dall'oggetto. Non posso davvero vederlo fare qualsiasi altra cosa. C'è un modo più efficiente per tentare questo? Il nodo lo ottimizza?

risposta

6

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.

+0

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]'). –

+2

@FelixKling - ha aggiunto ulteriori avvertimenti alla risposta. – jfriend00

+1

Per i casi in cui è necessario un clone profondo dell'oggetto, vedere questa risposta: http://stackoverflow.com/a/13333781/560114 –

-1

Se la rimozione dei metodi dal prototipo è ciò che si desidera, prendere in considerazione la creazione di un nuovo oggetto e il trasferimento su tutte le proprietà del vecchio oggetto.

Se si esclude proprietà che sono una funzione è ciò che si vuole, ciclo attraverso l'oggetto e verificare se la proprietà è una funzione:

for(key in ob) 
{ 
    if(typeof ob[key] === 'function') 
    { 
     delete ob[key]; 
    } 
} 

O forse ciò che si spera di realizzare è la combinazione di entrambi .

Problemi correlati