[英]Explaining odd behavior in javascript
我在推特上看到了這個,我也無法解釋。 以下面兩種方式定義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>
這里發生了什么?
前兩個示例為window.onload
屬性分配一個函數( window.
在第一個示例中是隱式的)。 onload
屬性實際上屬於window
的原型 (方便地稱為Window
)。
第三個變體聲明了一個具有相同名稱的新本地函數,該函數會從原型中隱藏屬性。 這意味着,當您要求window.onload
,引擎首先找到本地版本,並放棄查找原型鏈。 所以alert(window.onload);
確實提醒您的功能來源。 但是,要使事件處理程序起作用,必須將其分配給原型對象的onload
屬性。
但是,有一些奇怪的事情發生:當你嘗試分配一個從prototype
繼承的屬性時,它應該不起作用,並且應該在對象上創建一個“自己的”屬性,從原型中隱藏一個屬性(例如http://jsfiddle.net/ssBt9/ )。 但window
行為不同( http://jsfiddle.net/asHP7/ ),行為甚至可能因瀏覽器而異。
那是因為在腳本執行之前已經聲明了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=...
這不是一項聲明,只是一項不能懸掛的作業。
在前兩種情況下,您正在定義一個名為onload的窗口成員。 在第三種情況下,您只定義一個函數,但不是當前窗口的成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.