In Firefox 3.5, ich schreibe dies in der Konsole Firebug:JavaScript: {} == false ist ein SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Was hierfür ist die Erklärung?
In Firefox 3.5, ich schreibe dies in der Konsole Firebug:JavaScript: {} == false ist ein SyntaxError?
false=={} // => evals to false
{}==false // syntax error
Was hierfür ist die Erklärung?
{
zu Beginn einer Anweisung Signale ein 'Anweisungsblock' (siehe ECMA-262-3 Abschnitt 12.1), enthält eine Liste von Anweisungen.
}
beendet sofort den Anweisungsblock mit keinen Anweisungen darin. Das ist gut. Aber jetzt sucht der Parser nach der nächsten Anweisung:
==false
Huh? Das ist keine Aussage; Syntax-Fehler.
Was sind Anweisungsblöcke für?Nun, Sie werden jedes Mal ein Anweisungsblock Schreiben Sie sagen:
if (something) {
...
}
JavaScript definiert diese Flow-Control-Anweisungen wie:
if "(" <expression> ")" <statement> [else <statement>]
dh. in der einzigen Aussageform ohne Klammern. Es ermöglicht Ihnen dann, einen Anweisungsblock überall dort zu verwenden, wo Sie eine einzelne Anweisung verwenden können, was bedeutet, dass Sie if-braces-many-statements haben können. Es bedeutet aber auch, dass Sie selbst einen Anweisungsblock ohne zugehörige Flow-Control-Anweisung haben können.
Dies dient absolut keinem praktischen Zweck! Man könnte versucht zu denken, es gibt Ihnen Informationen deckenden, aber nicht:
var a= 1;
{
var a= 2;
}
alert(a);
... Ergebnisse in 2
, weil Anweisungsblocks für sich allein nicht einen neuen Bereich erstellen.
JavaScript definiert Ablaufsteuerungs- und Anweisungsblöcke auf diese Weise, weil C (und andere davon abgeleitete Sprachen) dies getan haben. Diese Sprachen haben {}
nicht als Objekt-Literalausdruck dienen, so dass sie nicht die Mehrdeutigkeit hatten, die dies zu einem anderen JS-Fehlverhalten macht.
Auch dieses wannabe-wörtliche:
{
a: 1
}
ist ein gültiger Anweisungsblock, weil ‚:‘ verwendet wird, ein Etikett in einer Erklärung zu bezeichnen. (und 1
ist eine nutzlose Ausdruckanweisung, wobei das Semikolon weggelassen wird.) Beschriftungen sind ein weiteres von C geerbtes Feature, das in JavaScript nur selten verwendet wird. Sie sind nicht völlig sinnlos wie die Blöcke, aber sie werden selten gebraucht und oft als geschmacklos betrachtet.
(Eine wörtliche mit zwei Eigenschaften wird einen Syntaxfehler verursachen, als Objektliterale Komma Separatoren verwenden, aber etikettierten Anweisungen durch ein Semikolon getrennt werden müssen.)
Dies ist not the only place wo JavaScript lösen Syntax Sie up, indem sie stolpern kann eine andere Aussage von etwas, von dem Sie denken, dass es ein Ausdruck ist.
OK, ich habe die studiert und ich habe eine Erklärung, die die BNF grammar diskussiert.
ECMAScript Quellen sind mit dem Hauptsymbol geparst beginnend genannt Program
:
Program:
SourceElements
SourceElements' (rekursiv) Definition ist folgende:
SourceElements :
SourceElement
SourceElements SourceElement
Das wird SourceElement definiert als:
SourceElement :
Statement
FunctionDeclaration
Was uns interessiert, ist die Objekt-Literal-Syntax, so dass wir ignorieren FunctionDeclaration und Blick auf die Erklärung Symbol:
Statement :
Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement
Ich bin nicht sicher, ob die Auflistung um Angelegenheiten (dies ist, wie sie in der Spezifikation sind), aber ... ein Objektliteral ist ein ExpressionStatement, über die sagen, dass die Normen der folgenden (Abschnitt 12.4):
Beachten sie, dass ein ExpressionStatement nicht mit einer Öffnung geschweiften Klammer beginnen kann, weil dass es zweideutig mit einem Block machen könnte. Außerdem kann ein ExpressionStatement nicht mit dem Funktionsschlüsselwort beginnen, da es es mit einer FunctionDeclaration möglicherweise mehrdeutig machen kann.
So können wir einen Ausdruck zu Beginn des Programms haben, aber es muss nicht mit einer Öffnung geschweifte Klammer ({
) beginnen. Deshalb ist die folgende Arbeit OK:
({} == false);
alert({} == false);
!{} == false;
-1 Ist keine echte Antwort (.. oder vielleicht bekomme ich nur Ihren Standpunkt nicht). Fühlen Sie sich frei, mich aufzuklären :) – roosteronacid
Sie sind völlig richtig. Ist eher ein Workaround. Ich durchsuche die ECMAScript 3-Spezifikation, um die richtige Antwort zu finden. Ich bin auch neugierig. –
Aye. Ich habe meine Down-Abstimmung aufgehoben. – roosteronacid
Einfach zu sagen, {}==false
werden von Js Compiler zu {};==false
kompiliert, so ist es Syntaxfehler. Sie sollten ({})==false
schreiben und es wird false zurückgeben.
Sein JavaScript ... damit umgehen. –
Interessant, aber was genau ist der Zweck davon? –
hm, 'false == {}' evals zu 'false' in meinem Firefox 3.5.3 – SilentGhost