Den*_*ret 6 javascript syntax grammar ecmascript-5
这更像是一个理论问题,而不是一个实际问题.它是关于解决由花括号分隔的一些代码.
以下是对象初始值设定项的两个示例:
f({});
({a:3})
Run Code Online (Sandbox Code Playgroud)
以下是两个块的示例:
;{}
{a:3;}
Run Code Online (Sandbox Code Playgroud)
实际上,{...}如果先前的代码需要表达式,那么它似乎会分开一个块.
但我从来没有在ECMAScript规范中看到这样的规则明确或明显,我甚至不确定它是否属实.
某处有明确的非模棱两可的参考吗?一个正确的规则,如果这个不是?
某处有明确的非模棱两可的参考吗?
它有点遍布整个规范.
简短的回答:
它取决于构造出现的上下文(这就是为什么它完全超出规范).可能它所解决的最具体的地方是§12.4,它表示ExpressionStatement(在预期语句时使用的表达式)不能以a开头{.
答案很长:
关键是解析器遇到{它时所期望的:如果它期望一个语句,那么它知道{开始一个块.但是如果它期望一个表达式,那么它知道{开始一个对象初始化器.我们看一下作业:
doThis(); // This line is just for context
x = {a: 3};
Run Code Online (Sandbox Code Playgroud)
在上面第二行的开头,解析器期待一个语句.但后来它看到x =并且知道它正在处理任务; 在那一点上,在看到之后=,解析器期待一个表达式.一个声明是无效的存在.所以它知道{启动对象初始化器,而不是块.
相反:
doThis(); // This line is just for context
{a: 3};
Run Code Online (Sandbox Code Playgroud)
上面的第二行是一个包含带标签的语句的块.(一个非常奇怪的一个;我们将回到那个.)解析器知道,因为在该行的开头,解析器期望一个语句,而不是一个表达式.
解析器期望看到表达式而不是语句的许多其他地方.例如,在:属性初始值设定项之后:
obj = {
prop: {a: 3}
};
Run Code Online (Sandbox Code Playgroud)
...或在进行函数调用时在参数内:
foo({a: 3});
Run Code Online (Sandbox Code Playgroud)
...或者在一元运算符之后,或者在开放之后(,等等.在规范中,您可以通过语法中解释器解析的内容来说明解析器将会期望什么,例如来自§的语法图12.5定义if声明:
IfStatement :
if ( Expression ) Statement else Statement
if ( Expression ) Statement
这告诉我们,在处理if语句时,()解析器中需要一个表达式,但在该if ()位之后,它需要一个语句.
到目前为止一直很好,但JavaScript允许(几乎)任何表达式允许的语句.这是有效的,例如:
doThis(); // This line is just for context
flag && doThat();
Run Code Online (Sandbox Code Playgroud)
上面的第二行是二元逻辑运算符表达式,但是是独立的.解析器在遇到它时期待一个语句.因此&&表达式是规范称为ExpressionStatement的表达式.ExpressionStatement由§12.4定义.
这让我们有些含糊不清:如果解析器期望一个语句,并且看到一个{,那么它如何知道这不是作为ExpressionStatement的对象初始化表达式的开头?
答案是:通过命令.:-)§12.4在定义ExpressionStatement时这样说:
注意ExpressionStatement不能以开括号大括号开头,因为这可能使其与Block不一致.
所以没有歧义,不是因为一些微妙的语法技巧,而是因为规范说明了这一点.:-)
(如果你有理由真的,真的想要使用对象初始化表达式作为语句,你可以这样做;只需将它放在其中().)
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |