JavaScript程序由語句和函數聲明組成。執行JavaScript程序時,會發生以下兩個步驟:在瀏覽器中爲單個網頁執行多少個JavaScript程序?
將掃描代碼以查找函數聲明和每個函數。聲明是「執行」的(通過創建一個函數對象)並且創建了該函數的命名引用(以便可以從語句內調用該函數)
該語句按順序執行(評估)出現在代碼)
正因爲如此,這作品就好:
<script>
foo();
function foo() {
return;
}
</script>
雖然宣佈收到「foo」的函數被調用,它的工作原理是因爲好玩陳述聲明在聲明前被評估。
然而,這不起作用:
<script>
foo();
</script>
<script>
function foo() {
return;
}
</script>
一個的ReferenceError將被拋出( 「沒有定義富」)。 這導致了這樣的結論:網頁的HTML代碼中的每個SCRIPT元素代表一個單獨的JavaScript程序,並且每當HTML分析器遇到SCRIPT元素時,它就執行該元素內的程序(然後一旦程序被執行,解析器移到跟在SCRIPT元素後面的HTML代碼中)。
然後,這種確實工作:
<script>
function foo() {
return;
}
</script>
<script>
foo();
</script>
我的理解這裏要說的是全局對象(其作爲在全球執行上下文的變量對象)存在(並保持)在任何時候,所以第一個JavaScript程序將創建函數對象併爲其創建引用,然後第二個JavaScript程序將使用該引用來調用該函數。因此,所有JavaScript程序(在單個網頁內)「使用」相同的全局對象,所有JavaScript程序所做的所有更改都可以被後續運行的所有JavaScript程序觀察到。
現在,注意到這...
<script>
// assuming that foo is not defined
foo();
alert(1);
</script>
在上述情況下,報警電話不會執行,因爲「富()」語句拋出一個的ReferenceError(它打破了整個JavaScript程序),因此,所有後續的語句都不執行。
然而,在這種情況下...
<script>
// assuming that foo is not defined
foo();
</script>
<script>
alert(1);
</script>
現在,警報呼叫沒有得到執行。第一個JavaScript程序拋出一個ReferenceError(並因此中斷),但第二個JavaScript程序正常運行。當然,瀏覽器會報告錯誤(儘管它在發生錯誤後執行了後續的JavaScript程序)。
現在,我的結論是:
- 的網頁的HTML代碼中的每個SCRIPT元素代表一個獨立的JavaScript程序。這些程序在HTML解析器遇到它們時立即執行。
- 同一網頁中的所有JavaScript程序「使用」相同的全局對象。該Global對象始終存在(從網頁被提取到網頁被銷燬的那一刻)。 JavaScript程序可能會操縱Global對象,並且可以在所有後續的JavaScript程序中觀察到由一個JavaScript程序對Global對象所做的所有更改。
- 如果一個JavaScript程序中斷(通過拋出錯誤),這並不妨礙後續的JavaScript程序執行。
請其實檢查這篇文章,並告訴我,如果我得到了什麼。
此外,我還沒有找到解釋本文中提到的行爲的資源,我假設瀏覽器製造商必須在某處發佈此類資源,因此如果您瞭解這些資源,請提供指向它們的鏈接。
更新!
OK,我要(試圖)從梅德A. Soshnikov這裏回答我的問題:) 我得到了(通過電子郵件)的響應(他經營着一個關於JavaScript的博客在http://www.dmitrysoshnikov.com/)。
他在這個問題上是這樣的:每個腳本塊包含全局代碼。執行每個SCRIPT塊會創建一個新的執行上下文。因此,每個SCRIPT塊都有自己的執行上下文,但所有這些執行上下文共享同一個全局對象。
SCRIPT塊可以被看作是不同的「子節目」具有相同的共享狀態。
此外,ECMAScript規範(第3版)規定(第10章): 「全局代碼是被視爲ECMAScript程序的源文本。」
鏈接解釋HOISTING。 http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting – Rajat 2010-10-14 21:02:26