根据this SO postCallExpression始终包含一个调用,因此不能成为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是否意味着规则同时涵盖了CallExpressionAsyncArrowHead,而他们只是决定将其放在14.7中而不是12.3中?
根据以上生产,以下内容将是有效的,因此与上面链接的SO帖子一起破坏了。我想念什么吗?如果NewExpression可以包含CallExpression,为什么还要将其分为NewExpressionCallExpression


显然有效:

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?


我也发现其他答案中的措辞有点难以理解,尽管我确实认为这是正确的。简短的答案是,然后将其分为NewExpressionCallExpression,因为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()()视为Argumentsnew MemberExpression Arguments中。由于CallExpression始终为函数调用处理(),因此NewExpression语法仅适用于构造可选的(),而

CallExpression:
  CoverCallExpressionAndAsyncArrowHead
  SuperCall
  CallExpression Arguments
  CallExpression [Expression]
  CallExpression .IdentifierName
  CallExpression TemplateLiteral


处理所有涉及没有()的函数调用的new情况。

09-30 21:58