onload=function与window.onload=function的区别

5
有没有使用window.onload=function(){};比onload=function(){};更好的优势?我知道window.onload看起来更正式,但这并不是我选择它的好理由,特别是因为它比onload更长/慢。经过一些耗时的搜索和测试,这两种方法是唯一兼容浏览器的方法,在相对较新的Chrome/Firefox版本和IE 5.5至9上进行了测试。
window.onload // works in all tested browsers
onload // works in all tested browsers, faster than window.onload
document.onreadystatechange // works twice in some browsers, once in some others, could be confusing
window.onpageshow // works in chrome and firefox, not in IE
window.onreadystatechange // doesn't work
document.onload // doesn't work
document.onpageshow // doesn't work
window.document.onload // doesn't work

我找到了这篇文章,它是与我的问题最相关的文章之一:

http://perfectionkills.com/onloadfunction-considered-harmful/

它指出ECMA-262第5版的严格模式("use strict";我不打算在我的项目中使用)最终可能导致某些浏览器不兼容onload(在Firefox和Opera中出现ReferenceError)。
因此问题是:除了"use strict;"之外,使用直接的onload赋值是否存在任何真正的缺点?我需要信息而不是一些没有解释的意见。
谢谢
注意:在提问之前,我进行了搜索(看起来有点老套),我能找到的最接近的问题是关于window.onload与<body onload="">、其他替代window.onload等的问题。
编辑:我创建了这个测试用例onload vs window.onload,证明了onload有多快。我真的会去做这种微小的优化,因为为什么不呢?它们有时候很酷。

据我所知,onload和window.onload是同义词。 - mplungjan
"onload...比window.onload更快" - 你是如何测试的?我很难想象你甚至能够测量出两者之间的性能差异。在实际代码中,肯定没有任何性能差异会成为因素。 - MrWhite
嗯,我的意思是 将 onload 分配 更快,我在 jsperf 上尝试过多次,在不同的浏览器上测试结果都是不容置疑的。这是一个新的测试案例:http://jsperf.com/onload-vs-window-onload。我知道它仍被认为是一种微小的优化,但这也是你可以学习一次并始终应用的东西。 - heytools
你的新测试似乎没有测试任何东西(你只是引用属性),自然地,对我来说这两个测试返回完全相同的结果(在Chrome 28中)。但是,正如你上面所述,赋值操作似乎会产生不同的结果,并且在这方面,“onload”似乎比“window.onload”稍微快一点。http://jsperf.com/onload-vs-window-onload/2 尽管如此,这只是微小的优化。 :) - MrWhite
我的错,我发布了错误的链接 http://jsperf.com/onload-window-onload - heytools
2个回答

3

两者是相同的...当你单独调用 onload 时,JavaScript 会认为它是 window 对象的全局属性。所以基本上如果你不明确说是 window.onload,JavaScript 引擎会自动为你做这件事。

if (onload === window.onload) {
   alert("it's the same");  //true
}

只要您不关心"严格模式",在现代浏览器上就不会有任何问题。然而,使用完整的"window.onload"而不仅仅是"onload"被认为更好。多打七个字符并没有多大的劣势。

是的,我需要对那个“however”进行解释。而且那个7个字符的句子不需要了,我已经说过onload不仅更短,而且更快。关于你的回答,请看我在Kaizo的回答下面的第一条评论。 - heytools
1
使用 window.onload 被认为是更好的做法,因为它避免了歧义,更易于阅读,因此使您的代码更具可移植性和 less prone to error。 您可能不会犹豫地使用 window.top,但是同样的原则也适用。 - MrWhite

1

所有的全局函数和变量都在window对象内部。因此,当您使用onload时,实际上是在使用window.onload

在调用命名空间中的内容时,会有性能成本:它必须获取window对象,然后才能获取属性onload。

如果在其作用域内没有使用window调用全局变量,则存在重定义风险:

function () {
  var onLoad = function() {alert("foo")};
  function () {
    onLoad();
  }
}

在这个例子中,onload弹出"foo";
所以你问,“使用直接的onload赋值是否存在任何真正的缺点”:
onload可能会被重新定义,代码可能无法工作。

如果(XMLHttpRequest)在一些旧版IE浏览器中无法工作,而(window.XMLHttpRequest)可以,因此我认为仅遵循一般规则是不够的。 - heytools
@Kaizo:在上面的代码中,onLoad需要全部小写才能隐藏全局的onload属性——假设这就是你所演示的。 - MrWhite
@heytools:你所说的“通用规则”是什么意思?你的例子似乎强调了浏览器的一个怪癖,而不是与Kaizo的代码相关。Kaizo的代码试图展示的是,在本地作用域中,onload并不一定指向全局的onload属性(即window.onload)- 这是有歧义的。而window.onload则不会出现这种情况。本地的onload变量会在作用域链中_隐藏_全局的onload属性。 - MrWhite
@w3d 通常的规则是:所有的全局函数和变量都在window对象中。我知道如何使用Chrome并验证window.onload == onload,但这并不足以得出结论,即使是在最老的浏览器/设备中也是如此。 - heytools
这就是关键所在,情况并不总是如此。当你不处于全局范围时,window.onload不一定等于onload。再看一遍你的例子,它不是浏览器的怪癖,你永远不应该使用if (globalVar)(例如在XMLHttpRequest中),因为当globalVar未定义时,它会抛出异常,而window.globalVar只会简单地返回_undefined_。 - MrWhite

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