如果一個文檔流中包含多個script代碼段(用script標簽分隔的js代碼或引入的js文件),運行順序是:
step1. 讀入第一個代碼段,JavaScript執行引擎並非一行一行地執行程序,而是一段一段地分析執行的(以<\script\>標簽來分割)
step2. 做語法分析,有錯則報語法錯誤(比如括號不匹配等),並跳轉到step5
step3. 對var變量做聲明(初始為undefined)和function定義做“預解析”(永遠不會報錯的,因為只解析正確的聲明)
step4. 執行代碼段,有錯則報錯(比如變量未定義)
step5. 如果還有下一個代碼段,則讀入下一個代碼段,重復step2
step6. 結束
JS的編譯過程:
眾所周知,javascript是解釋型語言,它不同於c#和java等編譯型語言。對於傳統編譯型語言來說,編譯步驟分為:詞法分析、語法分析、語義檢查、代碼優化和字節生成;但對於解釋型語言來說,通過詞法分析和語法分析得到語法樹后,就可以開始解釋執行了。
例子:
- alert(testNum);
- alert('ok');
- testNum = 2;
- //testNum未聲明,執行報錯。
- alert(testNum);
- alert('ok');
- var testNum = 2;
- //彈出undefined和ok。預編譯的時候,聲明了變量t;執行到alert(t)這行代碼的時候,t尚未被賦值,所以彈出undefined。
- testFunc();
- function testFunc() {}
- alert('ok');
- //彈出ok。預編譯的時候,解析了定義式函數語句function testFunc() {},順利執行。
- testFunc();
- var testFunc = function() {};
- alert('ok');
- //testFunc不是函數,執行報錯。預編譯的時候,聲明了變量testFunc = undefined;執行到testFunc()時,testFunc還等於undefined,不是函數,所以執行testFunc()會報錯。
- <\script type="text/javascript">
- testFunc();
- alert('first block');
- <!--\script-->
- <\script type="text/javascript">
- alert('second block');
- <!--\script-->
- //彈出second block。因為JS是一段一段執行的,第一段執行到testFunc()的時候報錯,整個第一段都不會再執行,第二段正常執行。