In Firefox 3.5, sto scrivendo questo nella console Firebug:JavaScript: {} == false è un SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Qual è la spiegazione per questo?
In Firefox 3.5, sto scrivendo questo nella console Firebug:JavaScript: {} == false è un SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Qual è la spiegazione per questo?
{
all'inizio di una dichiarazione segnala un 'blocco di istruzioni' (vedi ECMA-262-3 sezione 12.1), che contiene un elenco di dichiarazioni.
}
termina immediatamente il blocco di istruzioni senza istruzioni in esso. Va bene. Ma ora il parser sta cercando la prossima affermazione:
==false
Huh? Questa non è una dichiarazione; Errore di sintassi.
A cosa servono i blocchi di istruzioni?Bene, si sta scrivendo un blocco di istruzioni ogni volta che si dice:
if (something) {
...
}
JavaScript definisce queste affermazioni flusso di controllo come:
if "(" <expression> ")" <statement> [else <statement>]
es. nella singola forma di istruzione senza parentesi. Quindi consente di utilizzare un blocco di istruzioni ovunque sia possibile utilizzare una singola istruzione, il che significa che è possibile avere if-braces-many-statements. Ma significa anche che puoi avere un blocco di istruzioni da solo senza alcuna dichiarazione di controllo del flusso associata.
Questo non serve assolutamente a scopo pratico! Si potrebbe essere tentati di pensare che ti ha dato informazioni-nascondiglio, ma no:
var a= 1;
{
var a= 2;
}
alert(a);
... risultati in 2
, perché blocchi di istruzioni per sé non creare un nuovo ambito.
JavaScript definisce il controllo di flusso ei blocchi di istruzioni in questo modo perché C (e altri linguaggi derivati da esso) lo hanno fatto. Quelle lingue non hanno reso {}
il servizio double-duty come un'espressione letterale Object, quindi non avevano l'ambiguità che rende questo un altro JS misfeature.
Anche questo wannabe-letterale:
{
a: 1
}
è un blocco di istruzioni valida, perché ‘:’ è usato per indicare un'etichetta in un comunicato. (e 1
è un'istruzione espressione inutile, con il punto e virgola omesso.) Le etichette sono un'altra caratteristica ereditata da C che vengono raramente utilizzate in JavaScript. Non sono del tutto inutili come i blocchi, ma sono raramente necessari e spesso considerati di cattivo gusto.
(Un letterale con due proprietà causerà un errore di sintassi, come letterali oggetto usano separatori virgola, ma etichettati dichiarazioni devono essere separati da un punto e virgola.)
Questo è not the only place in cui la sintassi allentata di JavaScript può viaggio fino facendo qualche altra affermazione di qualcosa che pensi sia un'espressione.
OK, ho studiato il ECMAScript specification (PDF) e ho una spiegazione che discute il BNF grammar.
fonti ECMAScript vengono analizzati iniziando con il simbolo principale, chiamata Program
:
Program:
SourceElements
SourceElements' (ricorsiva) definizione è questa:
SourceElements :
SourceElement
SourceElements SourceElement
Il, SourceElement è definito come:
SourceElement :
Statement
FunctionDeclaration
Ciò che ci interessa è la sintassi letterale dell'oggetto, così ignoriamo FunctionDeclaration e guardiamo il simbolo Dichiarazione:
Statement :
Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
Non sono sicuro se le questioni di ordine parola (è il modo in cui sono nelle specifiche), ma ... un oggetto letterale è un ExpressionStatement, sul quale le norme dicono seguente (sezione 12.4):
noti che un ExpressionStatement non può iniziare con un'apertura ricci tutore perché potrebbe rendere ambiguo con un blocco. Inoltre, un ExpressionStatement non può iniziare con la parola chiave della funzione poiché tale potrebbe renderlo ambiguo con una FunctionDeclaration .
Così possiamo avere un'espressione all'inizio del programma, ma non deve iniziare con una parentesi graffa di apertura ({
). Ecco perché i seguenti lavori OK:
({} == false);
alert({} == false);
!{} == false;
-1 Non è una risposta reale (.. o forse non sto ottenendo il tuo punto). Sentiti libero di illuminarmi :) – roosteronacid
Hai perfettamente ragione. È piuttosto una soluzione. Sto cercando attraverso le specifiche ECMAScript 3 per trovare la vera risposta. Anch'io sono curioso anch'io. –
Sì. Ho annullato il mio voto negativo. – roosteronacid
Semplicemente per dire, {}==false
sono compilati dal compilatore Js a {};==false
, quindi è un errore di sintassi. dovresti scrivere ({})==false
e restituirà false.
Il suo JavaScript ... ha a che fare con esso. –
Interessante, ma qual è esattamente lo scopo? –
hm, 'false == {}' evalsa a 'false' nel mio Firefox 3.5.3 – SilentGhost