Javascript 表达式(o.method)()中忽略括号的原因
我想了解为什么表达式中的Javascript 表达式(o.method)()中忽略括号的原因,javascript,Javascript,我想了解为什么表达式中的o.method周围有括号 (o.method)() 被忽略,因此它的行为与o.method()相同,执行上下文为method引用o。我希望它的行为类似于(o.method | | true)(,其中方法中的执行上下文引用全局对象 如果我单独计算(o.method),它将返回对未绑定到任何上下文的独立函数的引用。就这么简单地重写吧 var a = (o.method); a(); 将具有预期的全局上下文。我刚刚通过替换a缩短了代码,它产生了不同的结果。这称为方法调用
o.method
周围有括号
(o.method)()
被忽略,因此它的行为与o.method()
相同,执行上下文为method
引用o
。我希望它的行为类似于(o.method | | true)(
,其中方法中的执行上下文引用全局对象
如果我单独计算(o.method)
,它将返回对未绑定到任何上下文的独立函数的引用。就这么简单地重写吧
var a = (o.method); a();
将具有预期的全局上下文。我刚刚通过替换a
缩短了代码,它产生了不同的结果。这称为方法调用。
当函数存储为对象的属性时,我们称之为方法。当调用一个方法时,它被绑定到该对象。如果调用表达式包含细化(即.dot表达式或[subscript]表达式),则将其作为方法调用
因此,在您的情况下,当您调用o.method时,它将引用对象“o”
在函数调用的情况下,这将调用窗口对象
请参考:我认为这与:
11.1.6分组运算符#Ⓣ
productionPrimaryExpression:(Expression)
的计算如下:
返回计算表达式的结果。这可能是参考类型
注意此算法不对表达式求值的结果应用GetValue。这样做的主要动机是,诸如delete
和typeof
之类的运算符可以应用于括号内的表达式
让我们看看函数调用是如何在JS中完成的:
关键点在于o.方法
是一个参考(由规范定义):
引用是已解析的名称绑定。引用由三个组件组成:基值、引用名称和布尔值严格引用标志
因此,o.method
还不是一个函数;它基本上是[[o,“method”,false]]
。使用参数列表调用时,o.method()
,引用值由GetValue获取,然后方法调用继续(如中所述)
当您执行(o.method)(
)时,(o.method)
仍然是一个参考-GetValue尚未应用于它(根据引用的11.1.6)。所以一切都没有改变
执行(o.method | | true)(
)时,| |
将在左侧(per)应用GetValue并生成函数值-不再是引用。因此,它不能作为方法调用进行评估,因为有关基名称和引用名称(在引用中存在)的信息丢失了。我知道这并不能回答括号问题,但您可以使用o.method.call()
来取消上下文也true
不是function@naomik是的,我知道,谢谢,出于某种原因,这个问题会反复从执行上下文而不是解析的角度来理解。我不理解你关于true
不是函数的评论,“o.method”只返回函数体。“在没有()的情况下访问函数将返回函数定义”@PAVANCHANDAKA queestion是,当调用o.method
时,此
应该指向窗口,而不是当前对象谢谢,直接指向该点。你把o
作为基值
放在这里[[o,“method”,false]]
,那么当你在全局上下文中定义一个函数foo
,然后引用它时,基值
被设置为窗口
,就像[[window,“foo”,false]]
一样,这是正确的吗?@Maximus:Yes,这也是我的理解。(虽然我必须承认我对“严格参考标志”有点模糊,但它与本次讨论无关。)太好了,谢谢。另外,我的理解是否正确,即在高层,GetValue
跟随指向内存地址的指针,检索位并将其解释为函数?更详细地说,foo
是一个问题,通过沿着环境链向上走,直到到达,在浏览器环境中,它是窗口
。(同时,我计算出了严格性标志:它是引用所在位置的当前严格性,正如我所认为的,在这里不相关。)不,它是一个函数。JavaScript中不存在引用——它们只存在于规范中,也可能存在于实现中,但在语言本身中没有这样的类型。根据中的variabledclaration:Identifier Initialiser
规则解析var a=…
时,引用将应用GetValue。实际上,该语言中几乎所有的计算都将应用GetValue,除了delete
、typeof
、分组括号以及赋值和声明中的左侧(可能我遗漏了一些,但不多)。