简体   繁体   English

在javascript中解释奇怪的行为

[英]Explaining odd behavior in javascript

I saw this on twitter and I couldn't explain it either. 我在推特上看到了这个,我也无法解释。 Defining a onload function in the following two manner works: 以下面两种方式定义onload函数有效:

1) JSFiddle 1) JSFiddle

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

2) JSFiddle 2) JSFiddle

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

But when defined like the following, it doesn't work even though it is assigned to window.onload 但是,如果定义如下,即使将其分配给window.onload ,它也不起作用

3) JSFiddle 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>​

What's going on here? 这里发生了什么?

The first two examples assign a function to the window.onload property ( window. is implicit in the first example). 前两个示例为window.onload属性分配一个函数( window.在第一个示例中是隐式的)。 The onload property actually belongs to the prototype of window (conveniently called Window ). onload属性实际上属于window原型 (方便地称为Window )。

The third variant declares a new local function with the same name, and that function shadows the property from the prototype. 第三个变体声明了一个具有相同名称的新本地函数,该函数会从原型中隐藏属性。 This means, when you ask for window.onload , the engine finds the local version first, and gives up looking up the prototype chain. 这意味着,当您要求window.onload ,引擎首先找到本地版本,并放弃查找原型链。 So alert(window.onload); 所以alert(window.onload); does alert your function source. 确实提醒您的功能来源。 However, for the event handler to work, it would have to be assigned to the prototype object's onload property. 但是,要使事件处理程序起作用,必须将其分配给原型对象的onload属性。

However, there is something odd going on: when you try to assign to a property that's inherited from the prototype , it shouldn't work, and an "own" property should be created on the object, shadowing the one from the prototype (eg http://jsfiddle.net/ssBt9/ ). 但是,有一些奇怪的事情发生:当你尝试分配一个从prototype继承的属性时,它应该不起作用,并且应该在对象上创建一个“自己的”属性,从原型中隐藏一个属性(例如http://jsfiddle.net/ssBt9/ )。 But window behaves differently ( http://jsfiddle.net/asHP7/ ), and the behavior may even vary depending on the browser. window行为不同( http://jsfiddle.net/asHP7/ ),行为甚至可能因浏览器而异。

That's because onload is already declared and null before your script executes. 那是因为在脚本执行之前已经声明了onload并且为null

This is similar to that code : 这类似于该代码:

var v=null;
function v(){
    console.log('hi');
}​​​​
console.log(v); // alerts null

which is different from this one : 这不同于这个:

function v(){
    console.log('hi');
}​​​​
console.log(v); // alerts the function

When you declare a function like this, the declaration and assignment are logically hoisted to the "start" of the scope, so the assignment doesn't really occur after the onload function is given the null value. 当声明这样的函数时,声明和赋值在逻辑上被提升到作用域的“开始”,因此在onload函数被赋予null之后实际上不会发生赋值。

That's why it's different from 这就是它与众不同的原因

window.onload=...

which isn't a declaration but only an assignment which can't be hoisted. 这不是一项声明,只是一项不能悬挂的作业。

In the first two cases your are defining a member of window called onload. 在前两种情况下,您正在定义一个名为onload的窗口成员。 In the third case your are only defining a function but is not a member of current window. 在第三种情况下,您只定义一个函数,但不是当前窗口的成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM