javascript
javascript运行机制之执行顺序详解
JavaScript是一種描述型腳本語言,它不同于java或C#等編譯性語言,它不需要進行編譯成中間語言,而是由瀏覽器進行動態(tài)地解析與執(zhí)行。那么JavaScript是怎么來進行解析的嗎?它的執(zhí)行順序又是如何的呢?在了解這些之前,我們先來認識幾個重要的術語:
1. 代碼塊
JavaScript中的代碼塊是指由<script>標簽分割的代碼段。例如:
JS是按照代碼塊來進行編譯和執(zhí)行的,代碼塊間相互獨立,但變量和方法共享。什么意思呢? 舉個例子,你就明白了
<script type="text/javascript"> alert(str);//因為沒有定義str,所以瀏覽器會出錯,下面的不能運行 alert("我是代碼塊一");//沒有運行到這里 var test = "我是代碼塊一變量"; </script> <script type="text/javascript"> alert("我是代碼塊二"); //這里有運行到 alert(test); //彈出"我是代碼塊一變量" </script>上面的代碼中代碼塊一中運行報錯,但不影響代碼塊二的執(zhí)行,這就是代碼塊間的獨立性,而代碼塊二中能調(diào)用到代碼一中的變量,則是塊間共享性。
2.聲明式函數(shù)與賦值式函數(shù)
JS中的函數(shù)定義分為兩種:聲明式函數(shù)與賦值式函數(shù)。
聲明式函數(shù)與賦值式函數(shù)的區(qū)別在于:在JS的預編譯期,聲明式函數(shù)將會先被提取出來,然后才按順序執(zhí)行js代碼。
3.預編譯和執(zhí)行期
事實上,JS的解析過程分為兩個階段:預編譯期(預處理)與執(zhí)行期。
預編譯期JS會對本代碼塊中的所有聲明的變量和函數(shù)進行處理(類似與C語言的編譯),但需要注意的是此時處理函數(shù)的只是聲明式函數(shù),而且變量也只是進行了聲明但未進行初始化以及賦值。
理解了上面的幾個術語,相信大家對JS的運行機制已經(jīng)有了個大概的印象了,現(xiàn)在我們來看個例子:
<script type="text/javascript"> Fn(); //瀏覽器報錯:"undefined" </script> <script type="text/javascript"> function Fn(){ //函數(shù)1 alert("執(zhí)行了函數(shù)1"); } </script>為什么運行上面的代碼瀏覽器會報錯呢?聲明函數(shù)不是會在預處理期就會被處理了嗎,怎么還會找不到Fn()函數(shù)呢?其實這是一個理解誤點,我們上面說了JS引擎是按照代碼塊來順序執(zhí)行的,其實完整的說應該是按照代碼塊來進行預處理和執(zhí)行的,也就是說預處理的只是執(zhí)行到的代碼塊的聲明函數(shù)和變量,而對于還未加載的代碼塊,是沒法進行預處理的,這也是邊編譯邊處理的核心所在。
現(xiàn)在,讓我們來總結整理下:
step 1. 讀入第一個代碼塊。
step 2. 做語法分析,有錯則報語法錯誤(比如括號不匹配等),并跳轉(zhuǎn)到step5。
step 3. 對var變量和function定義做“預編譯處理”(永遠不會報錯的,因為只解析正確的聲明)。
step 4. 執(zhí)行代碼段,有錯則報錯(比如變量未定義)。
step 5. 如果還有下一個代碼段,則讀入下一個代碼段,重復step2。
step6. 結束。
而根據(jù)HTML文檔流的執(zhí)行順序,需要在頁面元素渲染前執(zhí)行的js代碼應該放在前面的<script>代碼塊中,而需要在頁面元素加載完后的js放在元素后面,body標簽的onload事件是在最后執(zhí)行的。
作者: 卜卜口0?
鏈接:https://www.imooc.com/article/9009
來源:慕課網(wǎng)
轉(zhuǎn)載于:https://www.cnblogs.com/m2maomao/p/8257606.html
總結
以上是生活随笔為你收集整理的javascript运行机制之执行顺序详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle中查看最近被修改过的表的方法
- 下一篇: JS表格分页(封装版)