为什么在表达式(o.method)()中忽略括号

Why parenthesis are ignored in the expression (o.method)()

本文关键字:method 表达式 为什么      更新时间:2023-09-26

我想了解为什么在表达式

中围绕o.method的括号
(o.method)()

被忽略,因此它的行为与o.method()相同,method的执行上下文引用o。我希望它的行为类似于(o.method || true)(),其中method内的执行上下文引用全局对象。

如果我单独计算(o.method),它返回对未绑定到任何上下文的独立函数的引用。简单地重写成这样

var a = (o.method); a(); 

将像预期的那样具有全局上下文。我只是把a替换了,缩短了代码,产生了不同的结果。

我认为这与ES5 11.1.6有关:

11.1.6分组操作符#Ⓣ

产品PrimaryExpression : ( Expression )的评估如下:

  1. 返回Expression的求值结果。这可能是Reference类型。

该算法不对表达式的求值结果应用GetValue。这样做的主要动机是使deletetypeof这样的操作符可以应用于带括号的表达式。

让我们看看函数调用是如何在JS中完成的:

关键是o.method是一个引用(由规范定义):

引用是一个解析过的名称绑定。引用由三个部分组成:基值、引用名和布尔值严格引用标志。

所以,o.method还不是一个函数;基本上是[[o, "method", false]]。当使用参数列表o.method()调用时,引用值由GetValue获取,然后方法调用继续进行(如11.2.3所述)。

当你做(o.method)(), (o.method)仍然一个引用- GetValue仍然没有应用到它(按引用11.1.6)。所以什么都没变。

当您执行(o.method || true)()时,||将在左侧应用GetValue(根据11.11)并产生一个函数值-不再是Reference。因此,它不能作为方法调用进行计算,因为关于基名和引用名的信息(存在于Reference中)丢失了。

这叫做方法调用。当函数作为对象的属性存储时,我们称其为方法。当调用一个方法时,它被绑定到该对象。如果调用表达式包含细化(即。点表达式或[下标]表达式),则作为方法调用。

在你的例子中,当你调用。method时,this将引用对象'o'

this将在函数调用时调用window对象。

请参考:https://www.safaribooksonline.com/library/view/javascript-the-good/9780596517748/ch04s03.html