我在推特上看到了这个,我也无法解释。以下列两种方式定义onload
函数有效:
<html>
<head>
<script>
onload = function(){
alert('this works');
};
</script>
</head>
<body>
</body>
</html>
<html>
<head>
<script>
window.onload = function(){
alert('this works');
};
</script>
</head>
<body>
</body>
</html>
但是,如果定义如下,即使将其分配给window.onload
<html>
<head>
<script>
function onload(){
alert('this doesnt work');
};
alert(window.onload); // this shows the definition of above function
</script>
</head>
<body>
</body>
</html>
这里发生了什么?
答案 0 :(得分:9)
前两个示例将函数分配给window.onload
属性(window.
隐含在第一个示例中)。 onload
属性实际上属于window
的原型(方便地称为Window
)。
第三个变体声明了一个具有相同名称的新 local 函数,该函数会从原型中隐藏属性。这意味着,当您要求window.onload
时,引擎首先找到本地版本,然后放弃查找原型链。因此alert(window.onload);
会提醒您的功能来源。但是,要使事件处理程序起作用,必须将其分配给原型对象的onload
属性。
但是,有一些奇怪的事情:当你尝试分配一个继承自prototype
的属性时,它应该不起作用,并且应该在该对象上创建一个“自己的”属性,阴影来自原型的那个(例如http://jsfiddle.net/ssBt9/)。但window
表现不同(http://jsfiddle.net/asHP7/),行为甚至可能因浏览器而异。
答案 1 :(得分:3)
这是因为在脚本执行之前已经声明onload
并且null
。
这与代码相似:
var v=null;
function v(){
console.log('hi');
}
console.log(v); // alerts null
与此不同:
function v(){
console.log('hi');
}
console.log(v); // alerts the function
当您声明这样的函数时,声明和赋值在逻辑上被提升到作用域的“开始”,因此在 onload
函数之后实际上不会发生赋值给出null
值。
这就是为什么它与
不同window.onload=...
这不是声明,只是一项无法悬挂的作业。
答案 2 :(得分:0)
在前两种情况下,您正在定义一个名为onload的窗口成员。在第三种情况下,您只定义一个函数,但不是当前窗口的成员。