根据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部分? Cover是否意味着规则同时涵盖了CallExpression
和AsyncArrowHead
,而他们只是决定将其放在14.7
中而不是12.3
中?根据以上生产,以下内容将是有效的,因此与上面链接的SO帖子一起破坏了。我想念什么吗?如果
NewExpression
可以包含CallExpression
,为什么还要将其分为NewExpression
和CallExpression
?显然有效:
new new memberExpression(args);
这是
new new MemberExpression Arguments
,与第一个CallExpression
生产相同。 最佳答案
为什么在第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
需要括号,而NewExpression
要求没有括号。例如,从一般意义上讲,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
情况。