Ho notato oggi che Chrome 49 non viene più emesso NaN
quando si digita {}+{}
nella console. Invece genera la stringa [object Object][object Object]
.
Perchè è questo? La lingua è cambiata?
Ho notato oggi che Chrome 49 non viene più emesso NaN
quando si digita {}+{}
nella console. Invece genera la stringa [object Object][object Object]
.
Perchè è questo? La lingua è cambiata?
Risposte:
Gli sviluppatori Chrome ora avvolgono automaticamente tutto ciò che inizia {
e finisce con }
una coppia implicita di parentesi ( vedi codice ), per forzare la sua valutazione come espressione. In questo modo, {}
crea un oggetto vuoto ora. Puoi vedere questo se torni indietro nella cronologia ( ↑), la riga precedente sarà contenuta in (…)
.
Perché? Non lo so, ma immagino che riduca la confusione per i neofiti che non conoscono la cosa letterale block-vs-object, ed è anche più utile se vuoi solo valutare un'espressione.
E in effetti questo è il ragionamento, come discusso nel bug 499864 . Pura convenienza. E poiché anche il nodo REPL lo aveva ( vedi codice ).
{a:1}),({b:2}
dovrebbe generare un errore, non produrre un oggetto.
)
nel caso in cui sia in un commento, ad esempio {a:3} // :-}
potrebbe comunque produrre un oggetto.
Se premi la freccia su dopo aver verificato questo, noterai che invece di {} + {}
esso viene visualizzato ({} + {})
, il che si traduce in "[object Object][object Object]"
.
In confronto, in Firefox, {} + {}
viene ancora visualizzato NaN
, ma se lo fai ({} + {})
viene visualizzato anche "[object Object][object Object]"
.
Quindi, sembra che Chrome stia aggiungendo automaticamente la parentesi circostante quando vede questa operazione.
{} + {}
quando non "sanificato" ({} + {})
viene trattato come + {}
perché {}
viene analizzato come un blocco vuoto.
{}
è solo un blocco di codice vuoto e viene ignorato, lasciandoci con +{}
, che è un oggetto unario +
e vuoto initializer. +
costringerà il suo argomento al numero, che implica la conversione dell'oggetto in una primitiva (che finirà per essere un toString
in questo caso, risultante in "[object Object]"
), e quindi otteniamo +"[object Object]"
che è NaN
perché "[object Object]"
non può essere convertito in un numero valido.
Sfortunatamente, ho aggiunto io stesso la citazione di Clippy. La console non fornisce informazioni su ciò che ha fatto per te.
Le nuove regole sono incredibilmente semplici e ci risparmiano il problema di digitare faticosamente questi 2 caratteri difficili o=
o0,
prima di incollare Object Literals nella console:
{
;{wat:1}),({wat:2}
È finalmente di nuovo un errore.
{let i=0;var increment=_=>i++}
è correttamente consentito, infine, che è un bel modo di fare chiusure.
Tuttavia, quanto segue è erroneamente un oggetto, questo è altrettanto comodo come indicato da @Bergi, interpreta JS errato per aiutarti! La specifica dice che è un blocco con un'istruzione etichettata "pippo" con un 1 letterale che non è assegnato a nulla.
{foo:1}
Quanto sopra dovrebbe essere lo stesso di
if(1) {
foo: 1
}
Quello che segue è trattato correttamente come un blocco ... perché ha un commento davanti!
//magic comment
{foo:1}
Quindi è questo:
{foo:1}
//also magic
Questo è un oggetto:
{foo:
//not so magic comment
1}
Questo è un errore
//not so magic comment
{foo:1}.foo
Quindi è questo:
{foo:1}.foo
Questo va bene:
1..wat
undefined
così è questo:
['foo'][0]
Il prossimo viene correttamente interpretato come un oggetto inciso nella posizione dell'espressione con un 0,
che è generalmente il modo in cui assicuriamo inequivocabilmente di avere un'espressione invece di un'istruzione.
0,{foo:1}.foo
Non capisco perché racchiudano il valore in parentesi. JS ha alcune decisioni ridicole sul design, ma cercare di farlo funzionare meglio in questa situazione non è davvero un'opzione, la console deve eseguire correttamente JS e dobbiamo essere sicuri che Chrome non stia solo indovinando che pensa che noi intendevo davvero fare qualcos'altro.
Se non ti piacciono gli operatori virgola, puoi usare il compito
x = {foo:1}.foo
Perché così com'è
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Pazzo e coerente che posso affrontare ... pazzo e incoerente no grazie!
{foo:1}
e {foo:1}//
produci la stessa cosa. Nel Chrome JS REPL non lo fanno. Il REPL sta facendo molto di più che valutare JS. Sta elaborando le stringhe e decidendo di cose diverse.
var x = eval('{a:1}')
In JavaScript valido x ora è 1, non l'oggetto più intuitivo {a: 1}. Sì, è strano, ma non puoi semplicemente cambiare la lingua perché fa cose strane. Tutto tranne le stringhe JSON vengono interpretate come JavaScript e valutate. Digitare 0,
prima di incollare il JSON non è difficile, in alternativa sarei felice di avvertire che la stringa è stata interpretata come un oggetto anziché JavaScript per comodità.
var e = {}; e.toString()
e vedrai cosa intendo