括号如何影响 JavaScript 中的代码?

How do parentheses affect code in JavaScript?

var obj, method;

obj = {
  go: function() { console.log(this); }
};

(method = obj.go)()

注意:Fyodor 对他的回答的第一条评论对我帮助最大。正如主题所暗示的,这更多的是关于括号而不是 this.

在最后一行,我的理解是括号会强制里面的代码先到运行,所以methodgo的值属性, 这是一个函数。

() 然后调用该函数,该函数将 window 记录到控制台,因为它不是作为方法调用的。

如果您使用 method = obj.go() 而不是 (method = obj.go)(),它将首先 运行 go 函数,然后 method 将获取由它。由于 go returns 什么都没有,所以它将是 undefinedgo 打印的值将是 obj.

我不明白的是,为什么如果我执行 (obj.go)() 打印的 thisobj 而不是 window

考虑到其他代码的工作方式,我希望这段代码能像这样工作: obj.go 首先在括号内求值,然后函数 运行 作为 IIFE (function() { console.log(this); })()。因此,由于该函数未作为 obj 的方法调用,因此 this 默认为 window.

(method = obj.go)()分两步计算。

  1. method = obj.go 被评估并且 method var 等于对象 obj 的函数 go。 JavaScript 中的函数可以作为方法或函数调用,因此通常它不会影响您如何定义函数 go.

  2. 然后调用method()。由于您没有为 this 提供值(通过调用 method 函数作为某个对象的方法或使用 bindcall 它被调用 this设置为全局对象(在非严格模式下)或 undefined(在严格模式下)

当您调用 obj.go() 时,this 设置为等于 obj(类似于使用 obj.go.call(obj)method.call(obj))。如果你只调用 method() this 等于全局对象(类似于调用 obj.go.call(window)

编辑

并使用您的示例将 obj 设为 this,您可以这样做

(method = obj.go.bind(obj))()

通过这种方式,您不仅可以将 go 函数分配给变量 method,还可以创建绑定到特定 this 等于 obj

关于 function invocation and this in JavaScript

的好读物