淺談JavaScript 的執(zhí)行順序
雖然現(xiàn)代瀏覽器可以并行的下載JavaScript(部分瀏覽器),但考慮到JavaScript的依賴關(guān)系,他們的執(zhí)行依然是按照引入順序進行的。
本文章記錄本人在學(xué)習(xí) JavaScript 中看書理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復(fù)習(xí)。
在 html 文檔中的執(zhí)行順序
js代碼執(zhí)行順序比較的形象,用戶可以直觀的感受這種執(zhí)行順序。但是,js代碼的執(zhí)行順序是比較復(fù)雜的。有時候我們會把js代碼寫在html里面,而html文檔在瀏覽器中解析的過程是這樣:瀏覽器按照文檔流從上到下逐步解析頁面結(jié)構(gòu)和信息。js代碼作為嵌入的腳本也算做html文檔的組成部分,因此,js代碼在裝載時的執(zhí)行順序也是根據(jù)腳本標(biāo)簽<script>的出現(xiàn)來順序來決定。(下面一個栗子)
<!DOCTYPE html> <script> console.log("頂部腳本"); </script> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> console.log("頭部腳本"); </script> </head> <body> <script> console.log("頁面腳本"); </script> </body> </html> <script> console.log("底部腳本"); </script>
還有對于通過腳本標(biāo)簽<script>的src屬性導(dǎo)入的外部js文件腳本,它也將按照其語句出現(xiàn)的順序來執(zhí)行,而且執(zhí)行過程是文檔裝載的一部分,不會因為是外部js文件而延期執(zhí)行。
// 先加載 b.js 并且執(zhí)行里面的代碼 <script src="b.js"></script> // 然后在按順序執(zhí)行下面的代碼 <script> console.log(1); </script>
預(yù)編譯
當(dāng)js引擎解析的時候,它會在預(yù)編譯對所有聲明的變量和函數(shù)進行處理。
變量提升
console.log(a); // undefined var a = 1; console.log(a); // 1
預(yù)解析函數(shù)
f(); // 1 function f() { console.log(1); };
詳細:javascript變量聲明提升(hoisting)
分塊執(zhí)行代碼
js是按塊執(zhí)行代碼的,所謂代碼塊就是使用<script>標(biāo)簽分隔的代碼段。(下面一個栗子)
<script> // 代碼段1 var a = 1; </script> <script> // 代碼段2 function f() { console.log(1); }; </script>
因為js是按代碼塊來執(zhí)行的。瀏覽器在解析html文檔流的時候,如果遇到一個<script>標(biāo)簽,則js會等到這個代碼塊都加載完之后再對代碼進行預(yù)編譯,然后在執(zhí)行。執(zhí)行完畢后,瀏覽器會繼續(xù)解析西門的html文檔流,同時js也準(zhǔn)備好處理下一個代碼塊。
有個小坑,由于js是按塊執(zhí)行的,因此在一個js塊中調(diào)用后面塊聲明的變量或者函數(shù)就會提示語法錯誤。但是不同塊都屬于一個全局作用域,也就是說,塊之間的變量和函數(shù)是可以共享的。(下面一個栗子)
<script> // 代碼段1 console.log(a); f(); </script> <script> // 代碼段2 var a = 1; function f() { console.log(1); }; </script>
由于js是按塊處理代碼,同時又遵循h(huán)tml文檔流的解析順序,因此在上面的栗子中會看到語法錯誤。但是,在文檔流加載完畢后再次訪問就不會出現(xiàn)這種錯誤了。(下面一個栗子)
<script> window.onload = function(){ // 頁面初始化事件處理函數(shù) // 代碼段1 console.log(a); f(); } </script> <script> // 代碼段2 var a = 1; function f() { console.log(1); }; </script>
還有為了安全起見,一般在頁面初始化完畢之后才允許js代碼執(zhí)行,這樣就可以避免一些網(wǎng)速對js執(zhí)行的影響。同時,也避開了html文檔流對js執(zhí)行的限制。
綜上所述,javascript在執(zhí)行時的步驟是:
1、先讀入第一段代碼塊
2、對代碼塊進行語法分析,如果出現(xiàn)語法錯誤,直接執(zhí)行第5步驟
3、對var變量和function定義的函數(shù)進行“預(yù)編譯處理”(賦值式函數(shù)是不會進行預(yù)編譯處理的)
4、執(zhí)行代碼塊,有錯則報錯
5、如果還有下一段代碼塊,則讀入下一段代碼塊,重復(fù)步驟2
6、結(jié)束
相關(guān)文章
JS+CSS實現(xiàn)帶關(guān)閉按鈕DIV彈出窗口的方法
這篇文章主要介紹了JS+CSS實現(xiàn)帶關(guān)閉按鈕DIV彈出窗口的方法,實例分析了div彈出層窗口的實現(xiàn)技巧,非常具有實用價值,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02js實現(xiàn)3D粒子酷炫動態(tài)旋轉(zhuǎn)特效
這篇文章主要為大家詳細介紹了js實現(xiàn)3D粒子酷炫動態(tài)旋轉(zhuǎn)特效,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-09-09javascript將中國數(shù)字格式轉(zhuǎn)換成歐式數(shù)字格式的簡單實例
下面小編就為大家?guī)硪黄猨avascript將中國數(shù)字格式轉(zhuǎn)換成歐式數(shù)字格式的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08JS 動態(tài)獲取節(jié)點代碼innerHTML分析 [IE,FF]
在IE 環(huán)境下 賦值類型為對象時 innerHTML 獲取不到其改變,在FireFox環(huán)境下 .屬性 方式獲取不到其改變。2009-11-11