【问题标题】:How do parentheses affect code in JavaScript?括号如何影响 JavaScript 中的代码?
【发布时间】:2019-10-05 06:20:29
【问题描述】:

var obj, method;

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

(method = obj.go)()

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

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

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

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

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

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

【问题讨论】:

标签: javascript this parentheses


【解决方案1】:

(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的好书

【讨论】:

  • 我明白这一切。我理解为什么this 在您提到的所有情况下都是如此。我不明白的是为什么(obj.go)()obj.go()一样,但(method = obj.go)()method = obj.go()不一样。为什么(obj.go)() 中的括号会被忽略?
  • 括号与许多其他语言一样控制代码执行的顺序。所以对于(obj.go)(),括号的内部结构首先被评估。它评估为obj.go,因为括号内没有要评估的内容。然后obj.go() 被调用。当使用(method = obj.go)() 时,括号内有method = obj.go,所以这里有一些需要评估的东西。评估后method 等于goobj 方法,第二步只调用method()
  • 这只是归结为 . () 和 =
  • 谢谢@Fyodor。我现在知道了。如果我可以将此特定评论标记为我会的答案,因为它可以澄清我的具体疑问。所以我会标记整个事情。
猜你喜欢
  • 2017-08-23
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 2011-02-04
  • 2021-02-04
  • 2010-12-04
  • 2013-03-01
  • 2015-11-16
相关资源
最近更新 更多