2011-03-07 15 views
18

Oggi mi sono imbattuto in un comportamento davvero strano con javascript. Penso di averlo capito in qualche modo ora, ma mi piacerebbe sapere se ciò che penso stia accadendo davvero o se ci sia qualche altra magia coinvolta. Quindi questo è il mio codice:Perché console.log() non cattura un'istantanea delle variabili passate?

var SomeObject = {}; 

    SomeObject.foo = function(a, b) { 
     var baz = this.bar(a, b); 
     console.log(baz); 
     console.log(baz.left); 
     SomeObject.magicalStuff(baz); 
    }; 

    SomeObject.bar = function(a, b) { 
     return {left: a-b, top: b-a}; 
    }; 

    SomeObject.magicalStuff = function(position) { 
     position.left = 0; 
    }; 

    SomeObject.foo(100, 50); 

The code at jsFiddle

L'uscita di questo è qualcosa di simile (a seconda del browser):

> Object 
50 

Se si espande il "oggetto" (in Chrome, Safari o Firefox (Firebug) quello che ottieni è:

> Object 
    left: 0 
    top: -50 

Considerando che mi aspetto:

> Object 
    left: 50 
    top: -50 

Quello che penso sta succedendo è che console.log() in realtà solo "messaggi", un riferimento alla console, che viene letta una volta che si fa clic sul simbolo "espandere". Ma questo tipo di sconfiggere lo scopo di console.log() non è uno strumento di debug? Mi sono sempre aspettato console.log() per "fare lo snapshot" del materiale che ho passato. È davvero sorprendente vedere un'istruzione che viene dopo che l'effettivo console.log() cambia l'output di quella stessa chiamata a console.log().

Oppure c'è qualcos'altro?

Modifica: Mi chiedo anche se ci sia un motivo valido per gli sviluppatori di browser per implementare console.log come questo (suppongo ce ne sia uno, altrimenti non sarebbe coerente nei principali browser).

+1

Vedi https://bugs.webkit.org/show_bug.cgi?id=35801 –

+0

@Roatin Marth: Capisco. Ma perché dicono: "Non possiamo clonare l'oggetto scaricandolo nella console". Quali sono le difficoltà tecniche che non riesco a vedere? :) – fresskoma

+0

Questo è spesso visto quando si tenta di registrare un evento, poiché tutti gli eventi sono un singolo oggetto, di solito si sta guardando l'ultimo evento mousemove. –

risposta

10

C'è console.dir() per quello che vuoi in Firebug.

In generale, non è possibile stampare ogni livello di proprietà nidificate, dal momento che gli oggetti possono contenere riferimenti circolari come var a = {}; var b = {a: a}; a.b = b;

L'implementazione di un metodo perfetto clone è molto difficile - credo che avrebbe dovuto fondamentalmente solo scaricare tutta la memoria e il logging richiederebbe molto tempo. Pensa a console.log(window) ...

+0

Hai un punto lì. C'è qualcosa di simile per i browser Webkit come Safari e Chrome? – fresskoma

+0

Io non la penso così. Come suggerisce il [rapporto bug sopraindicato] (https://bugs.webkit.org/show_bug.cgi?id=35801), questo è un wontfix, e sicuramente '' console.dir() 'di Firefox basta solo a spingere il problema al livello successivo – user123444555621

+0

Si noti che 'console.dir' potrebbe non funzionare in Chrome. Ecco un confronto di soluzioni - http://jsfiddle.net/luken/M6295/ - prova a eseguirlo in Chrome. – Luke

6

Ho anche visto questo comportamento e sicuramente sembra che venga pubblicato un riferimento. Per aggirare questo ho usato il metodo clone() in jQuery sulle cose che volevo registrare.

+1

+1 Per una buona soluzione. Ma mi sto anche chiedendo perché console.log è implementato in questo modo. – fresskoma

+1

Immagino che la risposta di Nathan riguardo al sovraccarico possa avere qualcosa a che fare con questo. – jimmystormig

9

Sì, questo è quello che sta succedendo. Immagino sia fatto per minimizzare il sovraccarico delle chiamate console.log(). Le cose potrebbero andare fuori controllo se ogni oggetto è stato clonato in profondità per ogni chiamata di registro.

Quando è necessario risolvere il problema, è possibile eseguire l'operazione JSON.stringify() o clonare l'oggetto prima di passarlo a console.log().

+1

Sì, credo che tu abbia ragione. Tuttavia penso che console.log() sia una funzionalità di debug e tutto, dovrebbe essere un clone profondo. Ciò sarebbe meno sorprendente, almeno;) – fresskoma

+0

JSON.stringify può avere problemi con gli elementi HTML, poiché hanno riferimenti circolari. In quel caso ho usato outerHTML dell'elemento. –

Problemi correlati