根据this SO post,CallExpression
始终包含一个调用,因此不能成为new
运算符后面的表达式的一部分。
但是,ECMAScript 2017指出:
MemberExpression:
PrimaryExpression
MemberExpression [Expression]
MemberExpression .IdentifierName
MemberExpression TemplateLiteral
SuperProperty
MetaProperty
new MemberExpression Arguments
并且:
NewExpression:
MemberExpression
new NewExpression
并且:
CallExpression:
CoverCallExpressionAndAsyncArrowHead
SuperCall
CallExpression Arguments
CallExpression [Expression]
CallExpression .IdentifierName
CallExpression TemplateLiteral
并且:
CoverCallExpressionAndAsyncArrowHead:
MemberExpression Arguments
问题
MemberExpression Arguments
产品位于14.7 Async Arrow Function Definitions节中? 封面意味着规则同时涵盖了CallExpression
和AsyncArrowHead
,而他们只是决定将其放在14.7
中而不是12.3
中吗? li>
NewExpression
可以包含CallExpression
,为什么还要将其分为NewExpression
和CallExpression
?显然有效:
new new memberExpression(args);
哪个是new new MemberExpression Arguments
,与第一个CallExpression
作品相同。
答案 0 :(得分:1)
为什么在第14.7节“异步箭头功能定义”中找到MemberExpression Arguments生成? Cover是否表示规则同时涵盖CallExpression和AsyncArrowHead,而他们只是决定将其放在14.7中而不是12.3中?
这是因为async
不是关键字。这意味着在解析器中
async ()
只是对名为async
的函数的函数调用。这意味着在类似
async () =>
直到找到=>
为止,解析器无法知道其实际解析的语法类型。规范中通过所谓的“覆盖语法”来处理这种概念,即一组已知的令牌,具有多个可能的AST结构输出。
在规范中的一般情况下,这实际上意味着CoverCallExpressionAndAsyncArrowHead
定义了可以在箭头函数头或函数调用中找到的可能结构的并集。当解析器看到=>
时,它说:“好吧,我解析的CoverCallExpressionAndAsyncArrowHead
是箭头函数的头,如果它找到的内容不是=>
,那么它就知道了实际上是一个函数调用。
根据上述产生的结果,以下内容将是有效的,因此与上面链接的SO帖子一起破坏了。我想念什么吗?如果NewExpression可以包含CallExpression,为什么还要将其分为NewExpression和CallExpression?
我也发现其他答案中的措词有点难以理解,尽管我确实认为这是正确的。简短的答案是,然后将它们分成NewExpression
和CallExpression
,因为CallExpression
require parens,而NewExpression
要求在那里 not < / em>被原谅。例如,在一般意义上,new
是构造右侧内容的关键字。如果执行new Foo
,它将构造Foo
。如果执行new obj.Foo
,它将读取obj.Foo
,然后从中构造一个对象。这意味着从语法上讲,您几乎可以将它们视为等效:
// 1
var _tmp = Foo;
new _tmp;
// 2
var _tmp = obj.Foo;
new _tmp;
但这不是真的,因为它们是不同的:
// 3
var _tmp = Foo();
new _tmp;
// 4
new Foo();
new
关键字带有可选括号,正是这种行为使语法需要分开。如果我们看
NewExpression:
MemberExpression
new NewExpression
它总是直接跳到MemberExpression
,这意味着new obj()
会将()
视为Arguments
中的new MemberExpression Arguments
。由于CallExpression
始终处理()
进行函数调用,因此NewExpression
语法仅适用于构造可选的()
,而
CallExpression:
CoverCallExpressionAndAsyncArrowHead
SuperCall
CallExpression Arguments
CallExpression [Expression]
CallExpression .IdentifierName
CallExpression TemplateLiteral
处理所有()
情况,这些情况涉及不具有new
的函数调用。