Why do we write window.?

13

在为网页添加一些初始化代码时,我发现自己第umpteenth次写window.onload = ...,然后有个想法突然出现在我脑海中。

window.并不是必需的,因为window就是当前对象。所以它是可选的!
但是没有人仅仅写onload = ...,我想知道为什么。

我的意思是,我们毫不犹豫地写其他东西,比如说alert而不使用window.限定符。


window.onload = function() {
  alert('Your window has loaded');
};

实际上,alert方法和onload方法一样都是window对象的方法。
那么为什么会有这种区别? 为什么甚至像 W3C 这样的正式网站也会这样做呢?


17
它很明确,这样没有人会认为你只是偶然地给全局变量赋值。 - Bergi
1
我喜欢这个论点,因为它解释了不同之处。将某物分配给一个变量与调用一个函数-您无法通过仅调用它来创建新的函数,因此很明显该函数已经存在于某个地方。 - Mr Lister
@Bergi,你能把这个发表为答案吗?我认为这仍然是最有说服力的论点。 - Mr Lister
4个回答

8

当我们想要明确表示时,我们会写window。基本上有两种情况需要使用它:

  • window对象的属性和方法 - 所有属于{{link1:Window接口}}的内容。您提到的.onload监听器就是一个例子,像window.scrollY, window.status, window.parent, window.open(), window.focus(), window.removeEventListener()等都是其他例子。
  • 创建全局属性。从任何范围分配给window.myGlobalVar是一种常见的JS习惯用法,用于创建全局“变量”。不可否认,更好的做法仍然是使用var显式声明它。
虽然我们可以在这里“可选地”省略window.部分,但这是不常见的。特别是通过赋值创建隐式全局变量通常被视为错误。因此,如果您有意这样做,使用window.来声明您的意图。

然而,第一种情况并不总是定义明确的。当我们要使用的属性本质上是静态的全局变量,并且即使在正式指定它时也不一定与window对象相关联时,我们经常会省略window.部分。你很少看到有人使用documentatob()WorkersetTimeout()fetch()window.前缀,就像你不使用window.JSON.parsewindow.Array来处理内置对象一样(尽管这是有效的)。

对于一些其他属性,例如navigatorlocationalert(),并不总是很清楚,这些属性有时会使用,有时则不使用。


5
我看到以下原因:
  1. 减少查找范围链将稍微提高性能。在IIFE中也可以看到这一点,在其中,将window作为参数发送到函数中,并在其中使用对窗口的本地引用。
  2. 如果在作用域中覆盖了在window上全局定义的函数/成员,则它将不能按预期工作,因此明确引用会使其引用正确的函数/成员。这对于创建与全局名称相同的功能/成员且仍能从阴影范围访问全局成员非常有用。

1
好的,但为什么会有这种差异呢?为什么不是每个人都写window.alert而是alert,这样也可以提高性能呢? - Mr Lister
@MrLister请注意,`function onload() { // Code Here }onload = something;中的onload不会按预期工作。正如Andre在答案中所解释的那样,onload不仅限于window,它也可以应用于imgiframe等,因此它被显式地添加到了窗口上。在alert的情况下,它不是那么“关键”的函数,即使被覆盖也不会损坏代码(与onload`相反)。 - Tushar

1
因为 .onload 不仅限于 window,它也可以被用作例如 document.onload。所以你需要根据你希望脚本何时执行来定义它。

好的,但为什么会有这种差异呢?为什么不是每个人都写window.alert而是写alert,而且这也不是唯一的选择? - Mr Lister

-2

窗口对象默认由浏览器初始化。明确定义窗口对象有助于性能优化和代码可读性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接