ECMAScript 2017中的CallExpression与NewExpression

时间:2018-08-02 15:49:24

标签: javascript ecmascript-6 ecmascript-2017

根据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

问题

  1. 为什么MemberExpression Arguments产品位于14.7 Async Arrow Function Definitions节中? 封面意味着规则同时涵盖了CallExpressionAsyncArrowHead,而他们只是决定将其放在14.7中而不是12.3中吗? li>
  2. 根据上面的结果,下面的内容将是有效的,因此与上面链接的SO帖子相冲突。我想念什么吗?如果NewExpression可以包含CallExpression,为什么还要将其分为NewExpressionCallExpression

显然有效:

new new memberExpression(args);

哪个是new new MemberExpression Arguments,与第一个CallExpression作品相同。

1 个答案:

答案 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?

我也发现其他答案中的措词有点难以理解,尽管我确实认为这是正确的。简短的答案是,然后将它们分成NewExpressionCallExpression,因为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的函数调用。