淺談JavaScript的執行順序

雖然現代瀏覽器可以並行的下載JavaScript(部分瀏覽器),但考慮到JavaScript的依賴關係,他們的執行依然是按照引入順序進行的。

淺談JavaScript的執行順序

文章記錄本人在學習 JavaScript 中看書理解到的一些東西,加深記憶和並且整理記錄下來,方便之後的複習。

在 html 文件中的執行順序

js程式碼執行順序比較的形象,使用者可以直觀的感受這種執行順序。但是,js程式碼的執行順序是比較複雜的。有時候我們會把js程式碼寫在html裡面,而html文件在瀏覽器中解析的過程是這樣:瀏覽器按照文件流從上到下逐步解析頁面結構和資訊。js程式碼作為嵌入的指令碼也算做html文件的組成部分,因此,js程式碼在裝載時的執行順序也是根據指令碼標籤

的出現來順序來決定。(下面一個栗子) ("頂部指令碼");

("頭部指令碼");

("頁面指令碼");

("底部指令碼");

還有對於通過指令碼標籤

的src屬性匯入的外部js檔案指令碼,它也將按照其語句出現的順序來執行,而且執行過程是文件裝載的一部分,不會因為是外部js檔案而延期執行。 // 先載入 並且執行裡面的.程式碼

// 然後在按順序執行下面的程式碼

(1);

預編譯

當js引擎解析的時候,它會在預編譯對所有宣告的變數和函式進行處理。

變數提升

(a); // undefinedvar a = 1;(a); // 1

預解析函式

f(); // 1function f() { (1);};

詳細:javascript變數宣告提升(hoisting)

分塊執行程式碼

js是按塊執行程式碼的,所謂程式碼塊就是使用

標籤分隔的程式碼段。(下面一個栗子) // 程式碼段1 var a = 1;

// 程式碼段2 function f() { (1); };

因為js是按程式碼塊來執行的。瀏覽器在解析html文件流的時候,如果遇到一個

標籤,則js會等到這個程式碼塊都載入完之後再對程式碼進行預編譯,然後在執行。執行完畢後,瀏覽器會繼續解析西門的html文件流,同時js也準備好處理下一個程式碼塊。 有個小坑,由於js是按塊執行的,因此在一個js塊中呼叫後面塊宣告的變數或者函式就會提示語法錯誤。但是不同塊都屬於一個全域性作用域,也就是說,塊之間的變數和函式是可以共享的。(下面一個栗子) // 程式碼段1 (a); f();

// 程式碼段2 var a = 1; function f() { (1); };

由於js是按塊處理程式碼,同時又遵循html文件流的解析順序,因此在上面的栗子中會看到語法錯誤。但是,在文件流載入完畢後再次訪問就不會出現這種錯誤了。(下面一個栗子)

ad = function(){ // 頁面初始化事件處理函式 // 程式碼段1 (a); f(); }

// 程式碼段2 var a = 1; function f() { (1); };

還有為了安全起見,一般在頁面初始化完畢之後才允許js程式碼執行,這樣就可以避免一些網速對js執行的影響。同時,也避開了html文件流對js執行的限制。

綜上所述,javascript在執行時的步驟是:

1、先讀入第一段程式碼塊

2、對程式碼塊進行語法分析,如果出現語法錯誤,直接執行第5步驟

3、對var變數和function定義的函式進行“預編譯處理”(賦值式函式是不會進行預編譯處理的)

4、執行程式碼塊,有錯則報錯

5、如果還有下一段程式碼塊,則讀入下一段程式碼塊,重複步驟2

6、結束