3

我在推特上看到了这个,我也无法解释。onload以以下两种方式定义函数有效:

1)JSFiddle

<html>
    <head>
        <script>
            onload = function(){
                alert('this works');
            };
        </script>
</head>
<body>
</body>
</html>​

2)JSFiddle

<html>
    <head>
        <script>
            window.onload = function(){
                alert('this works');
            };
        </script>
</head>
<body>
</body>
</html>​

但是当像下面这样定义时,即使它被分配给它也不起作用window.onload

3)JSFiddle

<html>
    <head>
        <script>
            function onload(){
                alert('this doesnt work');
            };
            alert(window.onload); // this shows the definition of above function
        </script>
</head>
<body>
</body>
</html>​

这里发生了什么?

4

3 回答 3

9

前两个示例将函数分配给window.onload属性(window.在第一个示例中隐含)。该onload属性实际上属于(方便地称为)的原型windowWindow

第三个变体声明了一个新的同名本地函数,并且该函数隐藏了原型中的属性。这意味着,当你请求时window.onload,引擎首先找到本地版本,并放弃查找原型链。alert(window.onload);提醒您的函数源也是如此。但是,要使事件处理程序工作,必须将其分配给原型对象的onload属性。

但是,发生了一些奇怪的事情:当您尝试分配从prototype. ://jsfiddle.net/ssBt9/)。但window行为不同(http://jsfiddle.net/asHP7/),行为甚至可能因浏览器而异。

于 2012-12-10T18:31:58.930 回答
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

当你像这样声明一个函数时,声明和赋值在逻辑上被提升到作用域的“开始”,因此在函数被赋予值之后赋值不会真正发生。onloadnull

这就是为什么它不同于

window.onload=...

这不是一个声明,而只是一个不能提升的赋值。

于 2012-12-10T18:44:36.357 回答
0

在前两种情况下,您正在定义一个名为 onload 的窗口成员。在第三种情况下,您只定义一个函数,但不是当前窗口的成员。

于 2012-12-10T18:33:29.237 回答