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

时间:2016-11-01 05:36:58

标签: javascript

我想理解为什么表达式中的o.method括号

(o.method)()

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

如果我自己评估(o.method),它会返回对未绑定到任何上下文的独立函数的引用。只需像这样重写它

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

将具有预期的全局背景。我刚刚通过替换a缩短了代码,并产生了不同的结果。

2 个答案:

答案 0 :(得分:8)

我认为这与ES5 11.1.6

有关
  

11.1.6分组运算符#Ⓣ

     

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

     
      
  1. 返回评估Expression的结果。这可能是参考类型。
  2.         

    注意此算法不会将GetValue应用于评估Expression的结果。这样做的主要动机是,deletetypeof等运算符可以应用于带括号的表达式。

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

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

  

参考是已解析的名称绑定。 Reference由三个组件组成,基值,引用名称和布尔值严格引用标志。

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

当您执行(o.method)()时,(o.method) 仍然一个参考 - GetValue仍未应用于它(根据引用的11.1.6)。所以没有任何改变。

执行(o.method || true)()时,||会将GetValue应用到左侧(每11.11)并生成一个函数值 - 而不是参考。因此,它不能被评估为方法调用,因为有关基础和引用名称(参考中存在)的信息将丢失。

答案 1 :(得分:-3)

这称为方法调用。 当函数存储为对象的属性时,我们将其称为方法。调用方法时,它绑定到该对象。如果调用表达式包含细化(即.Point表达式或[subscript]表达式),则将其作为方法调用。

因此,在您调用o.method的情况下,这将引用对象' o'。

这将在函数调用的情况下调用window对象。

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