为什么我们要在全局变量前加上`window.`?

4
在许多互联网上看到的代码示例中,像 innerWidth, onresize, navigator 这样的全局变量通常写作 window.innerWidthwindow.onresizewindow.navigator 等。
为什么有些全局变量需要在前面加上 window. 而像 documentconsole 这样的通常不需要?
编辑:
我知道如何使用 OOP 并且可以访问各种 window 对象的属性。我不是 JavaScript 的新手。如果我的问题不够清晰,我很抱歉。我已经在 JS 中编程多年,但从未质疑这种惯例,因此提出了这个问题。
本质上,我要问的是为什么我们不在 document 前面加上 window.,而是在 innerWidth 前面加上它。这仅仅是为了清晰明了吗?理论上,我不应该能够引用任何没有 window. 前缀的全局变量而没有问题吗?

3
你需要阅读 MDN,这些对象非常易于理解。窗口是你的浏览器窗口,控制台是你的控制台,而文档则是页面文档。 - Sterling Archer
3
@SterlingArcher 我认为问题不在于每个变量代表什么,而是为什么有时会将window用作命名空间。 - Jonathan Lonowski
1
@JonathanLonowski 是的。 - Marcus McLean
2
为什么我们在document前面不加window.,而在innerWidth前面却加了呢?人们为什么对全局的undefined进行冗长的安全检查,但对其他全局变量却不进行?谁知道呢。我确实不知道。人们做些奇怪的事情。 - user1106925
如果没有同名的本地变量,我不应该能够引用任何全局变量而无需使用 window 前缀并且没有问题吗? - David Sherret
3个回答

6
很不幸,您浏览器中的window指代一个对象,代表两个逻辑上不同的概念:
  • Window实例,一个具有明确定义属性(如Window.innerWidth)的对象,逻辑上映射到您的浏览器窗口(或者说是标签页,但这个区别对于您的脚本来说是隐藏的)
  • 全局对象,所有全局变量都作为其属性附加
从语义上讲,不使用window.前缀更清晰,与Window概念无关的全局变量不需要前缀。
现在请注意,当您引用特定的全局变量(如myThing)时,会出现一个问题:很难知道您是故意引用全局变量还是它在某个中间范围内声明(或者您只是忘记使用var声明变量)。这将导致您不仅对Window实例的属性使用window.,而且对于您自己的特定全局变量也使用window.。当然,在实践中,您会尽可能避免使用全局变量。
不使用window.前缀的另一个好处是,当您忘记了var声明或库导入时,可以使您的代码在不明显的方式下快速失败(这比在生产环境中以难以调试的方式失败要好)。
window.undeclaredVariable // no error, just an undefined value
undeclaredVariable // reference error

如果 JavaScript 能够区分这两个概念的话,可能会更好(例如像 Node 中的 globalroot)。


那么这只是一个惯例问题吗? - Marcus McLean

1
所有的全局函数和变量都附加在对象activator上,这个对象依赖于您的主机环境(浏览器、节点等),在浏览器环境中,对象activator是窗口对象,因此每个全局函数都可以通过window.consolethis.consoleconsole访问,我认为prepend对于具有更可读性的代码很有用。
您可以在不使用window前缀的情况下访问全局作用域变量,只需使用innerWidth即可。

-1

把它想象成对象。你正在尝试获取window对象本身的innerWidth。同样,Document也是如此。你正在尝试获取描述document本身而不是整个window的变量。而console只是一个控制台,你可以用它来进行调试console.log。它也有自己的属性。

它们可能是全局变量,但它们仍然属于并描述了一个特定的“对象”,你必须首先调用该对象。如果这有意义的话。


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