2012-08-13 21 views
28

Eventuali duplicati:
What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?Perché {} + [] restituisce 0 in Javascript?

So che quando [] è costretto ad una stringa restituisce la stringa vuota (""), e quando {} è costretto ad una stringa restituisce "[object Object]" .

Quando eseguo [] + {} nella console JavaScript del mio browser, restituisce come mi sarei aspettato:

>> [] + {} 
"[object Object]" 

Ma quando ho eseguito {} + [], restituisce un valore del tutto inaspettato:

>> {} + [] 
0 

Cosa poteva far sì che restituisca 0?

+0

Sembra che si aggiunga null a null. Questo sarebbe equivalente a 0 + 0. Questa è solo un'ipotesi. – Trisped

+4

@Trisped: nessuno di questi è nulla. – SLaks

+2

Questa domanda è riassunta da http://stackoverflow.com/questions/9032856/what-is-the-explanation-for-these-bizarre-javascript-behaviours-mentioned-in-the (che ad oggi ha 301 voti) ..... –

risposta

49

Quando c'è un { all'inizio di una dichiarazione, sarà interpretato come un blocco, che può contenere zero o più istruzioni un blocco wi. non ci sono dichiarazioni in esso avrà un valore di continuazione vuoto.

In altre parole, in questo caso, {} viene interpretato come un blocco di codice vuoto.

L'istruzione termina dopo la parentesi finale }, il che significa che i tre caratteri successivi +[] comprendono una dichiarazione a parte.

All'inizio di un'espressione o di una frase, + è l'operatore unario più, che costringe il suo operando a un numero.

Quindi +[] è lo stesso di Number([]), che corrisponde a 0.

In breve, {} + [] è un blocco di codice vuoto seguito da un array forzato a un numero.


Detto questo, se si valuta {} + []all'interno di un'espressione, verrà restituito ciò che ci si aspetta:

>> ({} + []) 
"[object Object]" 

Un'altra cosa interessante è che non si può iniziare una dichiarazione con un oggetto letterale perché l'interprete proverà ad analizzarlo come una dichiarazione.In questo modo

{ "object": "literal" }; 

genererà un errore di sintassi.

+4

È interessante notare che un oggetto letterale con una singola proprietà non è un errore di sintassi all'inizio di un'istruzione se esci fuori dalle virgolette sul nome della proprietà. Semplicemente non significa come sembra. Ad esempio, '{oggetto:" letterale "}' viene interpretato come un'istruzione di blocco con una singola istruzione, '" letterale "'. 'object' diventa un'etichetta per la dichiarazione. –

+0

@MatthewCrumley Questo perché 'oggetto:' viene trattato come un'etichetta (quelli che è possibile utilizzare con le istruzioni break) –

18

Poiché lo {} viene considerato come un blocco. Così la vostra affermazione è in realtà:

{ 

//empty block here 
} 

+[] //0 same as Number([]) 

Questo è il motivo per cui questo è javascript valida:

eval('{hello: "world", key: "value"}') //Syntax error 

È possibile aggiungere() per renderlo un'espressione (blocchi non possono essere utilizzati in un'espressione così sarà inizializzazione degli oggetti:

eval('({hello: "world", key: "value"})') //Object 
+2

Non è immediatamente ovvio per me cosa c'è di sbagliato in questa risposta, quindi per favore spiega il downvote. – Esailija

+2

+1 per compensare downvote. Avevi circa 25 secondi prima e penso che il tuo esempio su più righe sia molto più chiaro – Izkata

2

Il blocco vuoto viene forzato in uno zero. Quindi l'operatore + decide di forzare lo [] a un numero.

+0

Il blocco vuoto è un blocco vuoto, non è forzato a nulla. – alex

+0

@alex, hai ragione, dopo aver letto la risposta di Peter Olsen, capisco che l'unica coercizione è la matrice in un numero e la prima serie di parentesi è semplicemente ignorata, l'ultima dichiarazione viene restituita –

Problemi correlati