JavaScript的執行順序
要了解JavaScript執行機制的順序,首先要先要對JavaScript有個初步的認識,我們先來認識幾個重要的術語和概念。
JavaScript是一種描述型指令碼語言,它不同於Java或C#等編譯性語言,它不需要進行編譯成中間語言,而是由瀏覽器進行動態的解析與執行。如果你不能理解JavaScript語言的執行機制,或者簡單地說,你不能掌握JavaScript的執行順序,那麼,就自然駕馭不了JavaScript。
1、程式碼塊
JavaScript中的程式碼塊是指由標籤分割的程式碼段。例如:
<script type="text/javascript">
alert("這是程式碼塊一");
</script>
<script type="text/javascript">
alert("這是程式碼塊二");
</script>
JS是按照程式碼塊來進行編譯和執行的,程式碼塊間相互獨立,但變數和方法共享。舉個例子:
<script type="text/javascript">
alert(str);//因為沒有定義str,所以瀏覽器會出錯,下面的不能執行
alert("我是程式碼塊一");//沒有執行到這裡
var test = "我是程式碼塊一變數";
</script>
<script type="text/javascript">
alert("我是程式碼塊二"); //這裡有執行到
alert(test); //彈出"我是程式碼塊一變數"
</script>
上面的程式碼中程式碼塊一中執行報錯,但不影響程式碼塊二的執行,這就是程式碼塊間的獨立性,而程式碼塊二中能呼叫到程式碼一中的變數,則是塊間共享性。
2、宣告式函式與賦值式函式
JS中的函式定義分為兩種:宣告式函式與賦值式函式。
<script type="text/javascript">
function Fn(){ //宣告式函式
}
var Fn = function{ //賦值式函式
}
</script>
宣告式函式與賦值式函式的區別在於:在JS的預編譯期,宣告式函式將會先被提取出來,然後才按順序執行js程式碼。
3、預編譯期與執行期
事實上,JS的解析過程分為兩個階段:預編譯期(預處理)與執行期。
預編譯期JS會對本程式碼塊中的所有宣告的變數和函式進行處理(類似與C語言的編譯),但需要注意的是此時處理函式的只是宣告式函式,而且變數也只是進行了宣告但未進行初始化以及賦值。
<script type="text/javascript">
Fn(); //執行結果:"執行了函式2",同名函式後者會覆蓋前者
function Fn(){ //函式1
alert("執行了函式1");
}
function Fn(){ //函式2
alert("執行了函式2");
}
</script>
<script type="text/javascript">
Fn(); //執行結果:"執行了宣告式函式",在預編譯期宣告函式及被處理了,所以即使Fn()呼叫函式放在宣告函式前也能執行。
function Fn(){ //宣告式函式
alert("執行了宣告式函式");
}
var Fn = function(){ //賦值式函式
alert("執行了賦值式函式");
}
</script>
//程式碼塊一
<script type="text/javascript">
alert(str);//瀏覽器報錯,但並沒有彈出資訊窗
</script>
//程式碼塊二
<script type="text/javascript">
alert(str); //彈窗"undefined"
var str = "aaa";
</script>
//js在預處理期對變數進行了宣告處理,但是並沒有進行初始化與賦值,所以導致程式碼塊二中的變數是undefined的,而程式碼一中的變數是完全不存在的,所以瀏覽器報錯。
理解了上面的幾個術語,相信大家對JS的執行機制已經有了個大概的印象了,現在我們來看個例子:
<script type="text/javascript">
Fn(); //瀏覽器報錯:"undefined"
</script>
<script type="text/javascript">
function Fn(){ //函式1
alert("執行了函式1");
}
</script>
為什麼執行上面的程式碼瀏覽器會報錯呢?宣告函式不是會在預處理期就會被處理了嗎,怎麼還會找不到Fn()函式呢?其實這是一個理解誤點,我們上面說了JS引擎是按照程式碼塊來順序執行的,其實完整的說應該是按照程式碼塊來進行預處理和執行的,也就是說預處理的只是執行到的程式碼塊的宣告函式和變數,而對於還未載入的程式碼塊,是沒法進行預處理的,這也是邊編譯邊處理的核心所在。
總結:
step 1. 讀入第一個程式碼塊。
step 2. 做語法分析,有錯則報語法錯誤(比如括號不匹配等),並跳轉到step5。
step 3. 對var變數和function定義做“預編譯處理”(永遠不會報錯的,因為只解析正確的宣告)。
step 4. 執行程式碼段,有錯則報錯(比如變數未定義)。
step 5. 如果還有下一個程式碼段,則讀入下一個程式碼段,重複step2。
step 6. 結束。
而根據HTML文件流的執行順序,需要在頁面元素渲染前執行的js程式碼應該放在前面的程式碼塊中,而需要在頁面元素載入完後的js放在元素後面,body標籤的onload事件是在最後執行的。
<script type="text/javascript">
alert("first");
function Fn(){
alert("third");
}
</script>
<body onload="Fn()">
</body>
<script type="text/javascript">
alert("second");
</script>
本文為Anyforweb技術分享部落格,需要了解網站建設相關,請訪問anyforweb.com。
相關文章
- JavaScript執行順序分析JavaScript
- pipeline的執行順序
- Sql執行順序SQL
- JavaScript是按順序執行的嗎?聊聊JavaScript中的變數提升JavaScript變數
- Spring Aop的執行順序Spring
- JavaScript程式碼執行順序和資料型別JavaScript資料型別
- mySQL 執行語句執行順序MySql
- SQL 語句的執行順序SQL
- mysql 語句的執行順序MySql
- 關於 Promise 的執行順序Promise
- 聊聊如何讓springboot攔截器的執行順序按我們想要的順序執行Spring Boot
- SQL語句執行順序SQL
- Select語句執行順序
- js執行順序Event LoopJSOOP
- sql mysql 執行順序 (4)MySql
- 【JavaScript】JS引擎中執行上下文如何順序執行程式碼JavaScriptJS行程
- 路由的中介軟體執行順序路由
- Pytest 順序執行,依賴執行,引數化執行
- async await、Promise、setTimeout執行順序AIPromise
- js解惑-函式執行順序JS函式
- [20191215]seq控制執行順序.txt
- sql select語法執行順序SQL
- 令人費解的 async/await 執行順序AI
- SQL語句各子句的執行順序SQL
- Java之執行緒的優先順序Java執行緒
- Jmeter的元件作用域和執行順序JMeter元件
- C#類中方法的執行順序C#
- 【高併發】深入理解執行緒的執行順序執行緒
- join、volatile、newSingleThreadLatch 實現執行緒順序執行thread執行緒
- Java中如何保證執行緒順序執行Java執行緒
- mysql 中sql語句關鍵字的書寫順序與執行順序MySql
- [20191112]flock控制命令執行順序.txt
- unittest--TestCase 按宣告順序執行
- Go包中程式碼執行順序Go
- kafka多執行緒順序消費Kafka執行緒
- 利用訊號量實現執行緒順序執行執行緒
- Laravel 多箇中介軟體的執行順序Laravel
- Js中async/await的執行順序詳解JSAI
- SQL 查詢語句的執行順序解析SQL