在javascript中解释奇怪的行为

时间:2012-12-10 18:29:32

标签: javascript

我在推特上看到了这个,我也无法解释。以下列两种方式定义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>​

这里发生了什么?

3 个答案:

答案 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的窗口成员。在第三种情况下,您只定义一个函数,但不是当前窗口的成员。