33

stavo aiutando un collega eseguire il debug del codice di oggi e ho notato uno strano comportamento con console.log() in Google Chrome:Google Chrome console.log() incoerenza con gli oggetti e gli array

Sembra che se:

  1. creare un array nidificato (ad esempio, [[345, "test"]])

  2. registro la matrice per la console con console.log().

  3. modificare uno dei valori di matrice interni, quindi console.log() stamperà il valore dopo - non fu eseguito i valori della matrice al momento della console.log().

JavaScript:

var test = [[2345235345,"test"]] 
console.log(test); 
test[0][0] = 1111111; 
// outputs: [[1111111,"test"]] 

var testb = {}; 
testb.test = "test"; 
console.log(testb); 
testb.test = "sdfgsdfg"; 
// outputs: {"testb":"test"} 


var testc = ["test","test2"]; 
console.log(testc); 
testc[0] = "sdxfsdf"; 
// outputs: ["test","test2"] 

JSFiddle Example

Questo comportamento non si verifica in Firefox.

Da notare anche che se ho eseguito il suo codice riga per riga nel debugger di Chrome, quindi console.log() restituirebbe i valori corretti.

C'è una spiegazione per questo strano fenomeno o è solo un bug con Google Chrome?

EDIT:

Ho ridotto i passaggi per riprodurre il comportamento incoerente console.log():

Se si aggiunge questo script per la pagina:

var greetings=['hi','bye']; 
console.log(greetings); 
setTimeout(function(){ 
    greetings.push('goodbye'); 
},3000); 

e apre in una nuova finestra con la finestra della console di Chrome è già aperta, quindi l'output di console.log() sarà diverso rispetto a quando si carica la pagina con la finestra della console chiusa. Here's a JSFiddle that demonstrates that.

Nel primo caso, con la finestra della console già aperta, console.log() emetterà il valore corrente dell'array (cioè due elementi).

Nel secondo caso, con la finestra di console inizialmente chiuso e aperto solo dopo al caricamento della pagina, console.log() stamperà i valori successivi della matrice (cioè tre elementi).

Si tratta di un bug nella funzionalità console.log() di Google Chrome?

+0

Anche se non so come, esattamente, questo non è un bug, Chrome fa questo genere di cose con una certa frequenza; puoi anche registrare il risultato di una richiesta AJAX; lo riempie retroattivamente, presumibilmente per chiarezza al momento del logging. Sono troppo inesperto per iniziare a spiegare perché, ho appena avuto un problema simile a confondermi.Tuttavia, qualsiasi codice che dipendesse dal valore corretto funzionerebbe correttamente. – Jonline

+1

Sembra che il valore registrato sulla console sia qualcosa di un valore * live *. Qualsiasi valore scalare all'interno degli oggetti di riferimento non verrà calcolato finché non si espanderanno gli oggetti in questione all'interno dell'output della console – Phil

+0

Sembra strano che i risultati di un 'console.log()' siano soggetti a qualcosa come una condizione di competizione. Quando passavo attraverso il codice dei miei colleghi, 'console.log()' restituiva i valori che ci aspettavamo, ma con un'esecuzione normale, emetterebbe un valore modificato successivamente - sembra che tu voglia i valori dell'array a il preciso momento in cui 'console.log()' viene eseguito. –

risposta

26

Dopo un sacco di scavi, ho scoperto che questo è stato segnalato come un bug, risolto in Webkit, ma apparentemente non ancora inserito in Google Chrome.

Per quanto posso dire, il problema è stato originariamente segnalato qui: https://bugs.webkit.org/show_bug.cgi?id=35801:

Descrizione Da Mitch Kramer 2010-03-05 11:37:45 PST

1) creare un oggetto letterale con una o più proprietà

2) console.log quell'oggetto ma lasciarlo chiuso (non espande nella console)

3) modificare una delle proprietà di un nuovo valore

ora apri quel console.log e vedrai che ha il nuovo valore per qualche motivo, anche se il suo valore era diverso al momento in cui è stato generato.

Devo sottolineare che se lo apri, manterrà il valore corretto se questo non fosse chiaro.

risposta da uno sviluppatore Cromo:

commento # 2 Dal Pavel Feldman 2010-03-09 06:33:36 PST

Non credo che stiamo sempre andando a fissare questo. Non possiamo clonare l'oggetto dopo averlo scaricato nella console e non possiamo nemmeno ascoltare le modifiche delle proprietà dell'oggetto per renderlo sempre attuale.

Dobbiamo assicurarci che il comportamento esistente sia previsto.

Una correzione era implementato due anni e mezzo dopo il 9 agosto 2012 per Webkit (http://trac.webkit.org/changeset/125174), ma non sembra aver fatto in Chrome ancora.

Ad oggi, lo scarico di un oggetto (matrice) in console comporterà proprietà degli oggetti essendo lettura all'espansione oggetto console (cioè pigramente). Ciò significa che scaricare lo stesso oggetto mentre è in corso la modifica di sarà difficile eseguire il debug utilizzando la console.

Questo cambiamento inizia a generare anteprime abbreviate per oggetti/matrici al momento della registrazione e passa queste informazioni nel front-end. Ciò accade solo quando il front-end è già aperto, funziona solo per console.log(), non per l'interazione con la console live.

+0

"Ciò significa che scaricare lo stesso oggetto mentre lo si muta sarà difficile per eseguire il debug usando la console ", l'ho capito solo pochi mesi fa e mi ha fatto impazzire. – Fahmi

+0

Grazie. Mi sto strappando i capelli da un paio di giorni cercando di capire cosa c'è di sbagliato nel mio codice. Qui è stato un problema con Chrome per tutto il tempo. – kojow7

+2

Il suo 2017 e ancora sta accadendo con valori di oggetti annidati. Ho passato ore ieri a eseguire il debug di un plug-in di codifica perché non mi mostrava i valori, si è scoperto che era chrome quando ho registrato l'obj assignment e nidificato obj prima/dopo. – OneEyed

3

Ho trovato una soluzione alternativa per questo bug/funzionalità.

console.log(JSON.parse(JSON.stringify(myObject))); 

Modifica: Purtroppo questo non funzionerà per valori non primitivi come le funzioni. Usa un'altra utility clone qui.

jQuery esempio:

console.log($.extend({}, myObject)); 
+0

Buona idea! È anche possibile sovrascrivere la funzione 'toString' –

+0

Sfortunatamente, non tutti gli oggetti possono essere modificati. ad es., 'JSON.stringify (document.body)' – ahui

Problemi correlati