2009-11-10 34 views
14

我希望有人能向我解釋爲什麼當在瀏覽器中查看HTML時,下面的JavaScript/HTML將顯示「門#2」:在聲明之前引用JavaScript值 - 可以有人解釋這個

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
    <script type="text/javascript"> 
     function testprint() { 
      alert('door #1'); 
     }; 

     window.onload = testprint; 

     function testprint() { 
      alert('door #2'); 
     }; 

     testprint = function() { 
      alert('door #3'); 
     }; 
    </script> 
    <script type="text/javascript"> 
     function testprint() { 
      alert('door #4'); 
     }; 
    </script> 
</head> 
<body> 
</body> 
</html> 

由於只有在window.onload設置爲testprint之前發生的聲明testprint,我期望window.onload原因'門#1'出現。實際上,onload會導致'2號門'。請注意,無論是否包含testprint的首次聲明,它都會執行此操作。

第三個和第四個聲明testprint使用不同的方式來分配函數,我試過這個看看它是否會覆蓋window.onload的行爲與第二個聲明testprint一樣。它沒。請注意,如果我將testprint的第四個聲明移到第一個腳本塊的末尾,它將被window.onload調用。

回答

38

函數聲明受到提升,並且它們在分析時進行評估,由提升裝置,它們可用於在它們被宣佈其中整個範圍,例如:

foo(); // alerts foo 
foo = function() { alert('bar')}; 
function foo() { alert('foo');} 
foo(); // alerts bar 

第一次調用foo將執行函數聲明,因爲分析時它提供的foo第二個電話會執行函數表達式,聲明在運行時

有關函數表達式和函數聲明之間差異的更詳細討論,請檢查this questionthis article

+0

在[瀏覽器不同意](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope#Conditionally_defining_a_function)中有一個微妙的函數提升。 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ** _ **將不會在**條件範圍內聲明提升函數, – 2013-11-04 10:38:56

-1

功能testprint是全局的頁面。 testprint = function ...指定一個變量,我不確定整個範圍的確切範圍,但是我發現它沒有像第一個那樣添加到函數表字典中。

0

原因#3不會改變window.onload是函數被引用而不是名稱調用。當您設置window.onload = testprint時,它會將當前值testprint(第2門,如CMS所解釋)分配給window.onload。稍後更改testprint的值不會影響window.onload的值。

4號門不會覆蓋2號門(除非,如您所說,將其移動到第一個腳本塊),因爲它位於不同的腳本塊中,所以在第一個塊完成後它會被解析。

相關問題