ECMAScript 2017 中的 CallExpression 与 NewExpression
CallExpression vs NewExpression in ECMAScript 2017
根据 ,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 post 不符。我错过了什么吗?为什么要分
NewExpression
和CallExpression
,如果NewExpression
可以包含CallExpression
?
显然有效:
new new memberExpression(args);
即 new new MemberExpression Arguments
,与第一个 CallExpression
产品相同。
Why is the MemberExpression Arguments production located in section 14.7 Async Arrow Function Definitions? Does Cover mean that the rule covers both CallExpression and AsyncArrowHead, and they just decided to put it in 14.7 instead of 12.3?
这是因为 async
不是关键字。这意味着在解析器中
async ()
只是对名为 async
的函数的函数调用。这意味着在
这样的片段的上下文中
async () =>
在找到 =>
之前,解析器无法知道它实际解析的语法类型。这个概念是一组已知的标记,具有多种可能的输出 AST 结构,在规范中通过所谓的覆盖语法处理。
在规范的一般情况下,这本质上意味着 CoverCallExpressionAndAsyncArrowHead
本质上定义了您可以在箭头函数头或函数调用中找到的可能结构的并集。当解析器看到 =>
时,它会说“好的,我解析的 CoverCallExpressionAndAsyncArrowHead
是箭头函数的头部,如果它发现 =>
以外的任何东西,那么它就知道它实际上是一个函数调用。
According to the above productions, the below would be valid, thus breaking with the SO post linked above. Am I missing something? Why divide it in NewExpression and CallExpression, if NewExpression can contain CallExpression?
我还发现其他答案中的措辞有点难以理解,但我确实认为它是准确的。简短的回答是 then 被分成 NewExpression
和 CallExpression
因为 CallExpression
需要 括号,而 NewExpression
需要 not 是括号。例如,一般意义上的 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()
会将 ()
视为 new MemberExpression Arguments
中的 Arguments
。由于 CallExpression
始终处理函数调用的 ()
,因此 NewExpression
语法仅适用于构造可选的 ()
,而
CallExpression:
CoverCallExpressionAndAsyncArrowHead
SuperCall
CallExpression Arguments
CallExpression [Expression]
CallExpression .IdentifierName
CallExpression TemplateLiteral
处理所有 ()
涉及 没有 new
.
的函数调用的情况
根据 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 post 不符。我错过了什么吗?为什么要分
NewExpression
和CallExpression
,如果NewExpression
可以包含CallExpression
?
显然有效:
new new memberExpression(args);
即 new new MemberExpression Arguments
,与第一个 CallExpression
产品相同。
Why is the MemberExpression Arguments production located in section 14.7 Async Arrow Function Definitions? Does Cover mean that the rule covers both CallExpression and AsyncArrowHead, and they just decided to put it in 14.7 instead of 12.3?
这是因为 async
不是关键字。这意味着在解析器中
async ()
只是对名为 async
的函数的函数调用。这意味着在
async () =>
在找到 =>
之前,解析器无法知道它实际解析的语法类型。这个概念是一组已知的标记,具有多种可能的输出 AST 结构,在规范中通过所谓的覆盖语法处理。
在规范的一般情况下,这本质上意味着 CoverCallExpressionAndAsyncArrowHead
本质上定义了您可以在箭头函数头或函数调用中找到的可能结构的并集。当解析器看到 =>
时,它会说“好的,我解析的 CoverCallExpressionAndAsyncArrowHead
是箭头函数的头部,如果它发现 =>
以外的任何东西,那么它就知道它实际上是一个函数调用。
According to the above productions, the below would be valid, thus breaking with the SO post linked above. Am I missing something? Why divide it in NewExpression and CallExpression, if NewExpression can contain CallExpression?
我还发现其他答案中的措辞有点难以理解,但我确实认为它是准确的。简短的回答是 then 被分成 NewExpression
和 CallExpression
因为 CallExpression
需要 括号,而 NewExpression
需要 not 是括号。例如,一般意义上的 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()
会将 ()
视为 new MemberExpression Arguments
中的 Arguments
。由于 CallExpression
始终处理函数调用的 ()
,因此 NewExpression
语法仅适用于构造可选的 ()
,而
CallExpression:
CoverCallExpressionAndAsyncArrowHead
SuperCall
CallExpression Arguments
CallExpression [Expression]
CallExpression .IdentifierName
CallExpression TemplateLiteral
处理所有 ()
涉及 没有 new
.