JavaScript: {}==false 是语法错误吗?
在 Firefox 3.5 中,我在 Firebug 控制台中输入以下内容:
false=={} // => evals to false
{}==false // syntax error
What is theterpretation for this ?
In Firefox 3.5, I type this in the Firebug console :
false=={} // => evals to false
{}==false // syntax error
What is the explanation for this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在声明开头表示“声明块”(请参阅 ECMA- 262-3 第 12.1 节),其中包含语句列表。
立即结束语句块,其中不包含任何语句。没关系。但现在解析器正在寻找下一条语句:
嗯?这不是一个声明;而是一个声明。语法错误。
语句块有什么用?好吧,每次你说:
JavaScript 将这些流程控制语句定义为:
即 ,你都在编写一个语句块。以不带大括号的单语句形式。然后,它允许您在可以使用单个语句的任何地方使用语句块,这意味着您可以拥有 if-braces-many-statements。但这也意味着您可以拥有一个独立的语句块,而无需关联的流程控制语句。
这绝对没有任何实际目的!您可能会认为它隐藏了信息,但事实并非如此:
...
2
中的结果,因为语句块本身并不创建新的作用域。JavaScript 以这种方式定义流程控制和语句块,就像 C(以及从它派生的其他语言)所做的那样。不过,这些语言并没有使
{}
作为对象文字表达式发挥双重作用,因此它们不存在使这成为另一个 JS 错误功能的歧义。即使这个wannabe-literal:
也是一个有效的语句块,因为':'用于表示语句中的标签。 (
1
是一个无用的表达式语句,省略了分号。)标签是从 C 继承的另一个功能,在 JavaScript 中很少使用。它们并不像积木那样完全毫无意义,但它们很少被需要,而且常常被认为品味不佳。(具有两个属性的文字将导致语法错误,因为对象文字使用逗号分隔符,但带标签的语句必须用分号分隔。)
这是 这并不是唯一的地方,JavaScript 的松散语法可能会因为对您认为是表达式的内容进行其他声明而使您陷入困境。
at the start of a statement signals a ‘statement block’ (see ECMA-262-3 section 12.1), which contains a list of statements.
immediately ends the statement block with no statements in it. That's fine. But now the parser is looking for the next statement:
Huh? That's not a statement; syntax error.
What are statement blocks for? Well, you are writing a statement block every time you say:
JavaScript defines these flow-control statements as:
ie. in the single statement form with no braces. It then allows you to use a statement-block anywhere you can use a single statement, which means you can have if-braces-many-statements. But it also means you can have a statement-block on its own with no associated flow-control statement.
This serves absolutely no practical purpose! You might be tempted to think it gave you information-hiding, but no:
...results in
2
, because statement blocks don't in themselves create a new scope.JavaScript defines flow control and statement blocks in this manner because C (and other languages derived from it) did. Those languages didn't make
{}
serve double-duty as an Object literal expression though, so they didn't have the ambiguity that makes this another JS misfeature.Even this wannabe-literal:
is a valid statement block, because ‘:’ is used to denote a label in a statement. (and
1
is a useless expression-statement, with the semicolon omitted.) Labels are another feature inherited from C that are rarely used in JavaScript. They're not totally pointless like the blocks, but they're seldom needed and often considered in poor taste.(A literal with two properties will cause a syntax error, as object literals use comma separators, but labelled statements must be separated by semicolons.)
This is not the only place where JavaScript's loose syntax can trip you up by making some other statement of something you think is an expression.
好的,我已经研究了 ECMAScript 规范 (PDF) 我有一个讨论 BNF 语法 的解释。
ECMAScript 源从主符号开始解析,称为
Program
:SourceElements 的(递归)定义是这样的:
SourceElement 定义为:
我们感兴趣的是对象字面量语法,所以我们忽略 FunctionDeclaration 并查看 Statement 符号:
我不确定列表顺序是否重要(这就是它们在规范中的方式),但是......对象文字是一个 ExpressionStatement,标准对此有以下说明(部分12.4):
因此,我们可以在程序开头有一个表达式,但它不能以左大括号 (
{
) 开头。这就是为什么下面的代码可以正常工作:({} == false);
alert({} == false);
!{} == false;
代码>OK, I've studied the ECMAScript specification (PDF) and I have an explanation which discuses the BNF grammar.
ECMAScript sources are parsed starting with the main symbol, called
Program
:SourceElements' (recursive) definition is this:
The, SourceElement is defined as:
What we're interested in is the object literal syntax, so we ignore FunctionDeclaration and look at the Statement symbol:
I'm not sure if the listing order matters (this is how they are in the spec), but... an object literal is an ExpressionStatement, about which the standards say the following (section 12.4):
So we may have an expression at the start of the program, but it must not start with an opening curly brace (
{
). That's why the following work OK:({} == false);
alert({} == false);
!{} == false;
简单来说,
{}==false
被Js编译器编译为{};==false
,所以是语法错误。你应该写({})==false
它会返回 false。Simply to say,
{}==false
are compiled by Js compiler to{};==false
, so it's syntax error. you should write({})==false
and it'll return false.