【发布时间】:2010-07-22 13:48:51
【问题描述】:
我注意到像 setTimeout() 这样的调用可以作为:
self.keyword()
或仅靠他们自己,例如keyword()。
这两个调用有什么不同?
【问题讨论】:
标签: javascript
我注意到像 setTimeout() 这样的调用可以作为:
self.keyword()
或仅靠他们自己,例如keyword()。
这两个调用有什么不同?
【问题讨论】:
标签: javascript
self 可以引用窗口对象,但通常情况并非如此。你会在上面看到这个setTimeout():
var self = this;
他们保留对当前对象的引用,所以稍后当您调用self.keyword() 时,您将调用该方法该对象,而不是其他任何方法。
假设您在页面中有想要每 2 秒旋转一次的图像...您希望这 3 个计时器中的每一个都引用它们自己的方法。如果他们直接使用this,它将(大多数时候)引用window 而不是当前对象,而传入另一个变量来维护当前引用。
【讨论】:
setTimeout() 本身是一个全局函数,但它可以执行任何函数,例如:setTimeout(myFunction, 1000); 或 setTimeout(function() { alert(this); }, 1000);
它适用于setTimeout,因为浏览器中有两个条件:
window 对象的属性。这意味着window 有一个属性setTimeout (window.setTimeout)。window 对象有一个名为 self 的属性,它指向自身。由于您可以访问window 的属性而无需显式编写window(这就是使全局变量成为全局变量的原因),因此两个调用都有效:setTimeout() 将在窗口对象上查找属性setTimeout()。 self.setTimeout() 将在 window 对象上查找属性 self,这是窗口对象本身。
因此,如果您调用self.setTimeout(),它与window.self.setTimeout() 相同,与window.setTimeout() 相同,与setTimeout() 相同。
注意:只有在当前作用域中没有定义变量 self 来影响全局 self 时,这才有效。
这适用于在全局范围内定义的 any 符号(表示变量或函数)。你可以自己测试一下:
alert(window.self);
和
alert(self);
都应该警惕
[object Window]
【讨论】:
setTimeout 是window 对象的一个方法,它恰好看起来是全局的,因为window 指向全局对象。
window 对象上的每个属性和方法都可以在有或没有“窗口”的情况下调用。
和
self 是 window 对象的一个只读属性,它返回窗口本身 (MDN)
所以
setTimeout()
window.setTimeout()
window.self.setTimeout()
self.setTimeout()
都是一样的东西。
使用self.setTimeout() 而不是window.setTimeout() 或任何其他方式的主要优点是,如果您在WebWorker 中运行一些调用window.setTimeout() 的代码,它将失败,但self.setTimeout() 将在Web Worker 中运行和浏览器上下文。因此,如果您正在编写一个既适用于主窗口范围又适用于 Web Worker 的库,我们应该更喜欢使用 self.
self 始终指的是 GlobalScope,在浏览器模式下是 window 而在 web 工作者内部是 `WorkerGlobalScope'
【讨论】: