欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解javascript的執(zhí)行順序

 更新時(shí)間:2014年04月04日 13:44:04   作者:  
JavaScript是一種描述型腳本語(yǔ)言,它不同于java或C#等編譯性語(yǔ)言,它不需要進(jìn)行編譯成中間語(yǔ)言,而是由瀏覽器進(jìn)行動(dòng)態(tài)地解析與執(zhí)行

如果你不能理解javaScript語(yǔ)言的運(yùn)行機(jī)制,或者簡(jiǎn)單地說(shuō),你不能掌握javascript的執(zhí)行順序,那你就猶如伯樂(lè)駕馭不了千里馬,讓千里馬脫韁而出,四處亂竄。

那么JavaScript是怎么來(lái)進(jìn)行解析的嗎?它的執(zhí)行順序又是如何的呢?在了解這些之前,我們先來(lái)認(rèn)識(shí)幾個(gè)重要的術(shù)語(yǔ):

1、代碼塊
JavaScript中的代碼塊是指由<script>標(biāo)簽分割的代碼段。例如:

復(fù)制代碼 代碼如下:

<script type="text/javascript">
      alert("這是代碼塊一");
</script>
<script type="text/javascript">
      alert("這是代碼塊二");
</script>

JS是按照代碼塊來(lái)進(jìn)行編譯和執(zhí)行的,代碼塊間相互獨(dú)立,但變量和方法共享。什么意思呢? 舉個(gè)例子,你就明白了:

復(fù)制代碼 代碼如下:

<script type="text/javascript">
      alert(str);//因?yàn)闆](méi)有定義str,所以瀏覽器會(huì)出錯(cuò),下面的不能運(yùn)行
      alert("我是代碼塊一");//沒(méi)有運(yùn)行到這里
      var test = "我是代碼塊一變量";
</script>
<script type="text/javascript">
      alert("我是代碼塊二"); //這里有運(yùn)行到
      alert(test); //彈出"我是代碼塊一變量"
</script>

上面的代碼中代碼塊一中運(yùn)行報(bào)錯(cuò),但不影響代碼塊二的執(zhí)行,這就是代碼塊間的獨(dú)立性,而代碼塊二中能調(diào)用到代碼一中的變量,則是塊間共享性。

2、聲明式函數(shù)與賦值式函數(shù)


JS中的函數(shù)定義分為兩種:聲明式函數(shù)與賦值式函數(shù)。

復(fù)制代碼 代碼如下:

<script type="text/javascript">
     function Fn(){ //聲明式函數(shù)

     }

     var Fn = function{  //賦值式函數(shù)

     }
</script>

聲明式函數(shù)與賦值式函數(shù)的區(qū)別在于:在JS的預(yù)編譯期,聲明式函數(shù)將會(huì)先被提取出來(lái),然后才按順序執(zhí)行js代碼。

3、預(yù)編譯期與執(zhí)行期


事實(shí)上,JS的解析過(guò)程分為兩個(gè)階段:預(yù)編譯期(預(yù)處理)與執(zhí)行期。

預(yù)編譯期JS會(huì)對(duì)本代碼塊中的所有聲明的變量和函數(shù)進(jìn)行處理(類(lèi)似與C語(yǔ)言的編譯),但需要注意的是此時(shí)處理函數(shù)的只是聲明式函數(shù),而且變量也只是進(jìn)行了聲明但未進(jìn)行初始化以及賦值。

復(fù)制代碼 代碼如下:

<script type="text/javascript">
     Fn();  //執(zhí)行結(jié)果:"執(zhí)行了函數(shù)2",同名函數(shù)后者會(huì)覆蓋前者
     function Fn(){ //函數(shù)1
        alert("執(zhí)行了函數(shù)1");
     }

     function Fn(){  //函數(shù)2
        alert("執(zhí)行了函數(shù)2");
     }
</script> 
<script type="text/javascript">
      Fn();  //執(zhí)行結(jié)果:"執(zhí)行了聲明式函數(shù)",在預(yù)編譯期聲明函數(shù)及被處理了,所以即使Fn()調(diào)用函數(shù)放在聲明函數(shù)前也能執(zhí)行。
      function Fn(){ //聲明式函數(shù)
         alert("執(zhí)行了聲明式函數(shù)");
      }

      var Fn = function(){  //賦值式函數(shù)
         alert("執(zhí)行了賦值式函數(shù)");
      }
</script>

//代碼塊一
<script type="text/javascript">
      alert(str);//瀏覽器報(bào)錯(cuò),但并沒(méi)有彈出信息窗
</script>
//代碼塊二
<script type="text/javascript">
      alert(str); //彈窗"undefined"
      var str = "aaa";
</script>
//js在預(yù)處理期對(duì)變量進(jìn)行了聲明處理,但是并沒(méi)有進(jìn)行初始化與賦值,所以導(dǎo)致代碼塊二中的變量是unfiened的,而代碼一中的變量是完全不存在的,所以瀏覽器報(bào)錯(cuò)。

理解了上面的幾個(gè)術(shù)語(yǔ),相信大家對(duì)JS的運(yùn)行機(jī)制已經(jīng)有了個(gè)大概的印象了,現(xiàn)在我們來(lái)看個(gè)例子:

復(fù)制代碼 代碼如下:

<script type="text/javascript">
      Fn();  //瀏覽器報(bào)錯(cuò):"undefined"
</script>
<script type="text/javascript">
      function Fn(){ //函數(shù)1
          alert("執(zhí)行了函數(shù)1");
      }
</script>

為什么運(yùn)行上面的代碼瀏覽器會(huì)報(bào)錯(cuò)呢?聲明函數(shù)不是會(huì)在預(yù)處理期就會(huì)被處理了嗎,怎么還會(huì)找不到Fn()函數(shù)呢?其實(shí)這是一個(gè)理解誤點(diǎn),我們上面說(shuō)了JS引擎是按照代碼塊來(lái)順序執(zhí)行的,其實(shí)完整的說(shuō)應(yīng)該是按照代碼塊來(lái)進(jìn)行預(yù)處理和執(zhí)行的,也就是說(shuō)預(yù)處理的只是執(zhí)行到的代碼塊的聲明函數(shù)和變量,而對(duì)于還未加載的代碼塊,是沒(méi)法進(jìn)行預(yù)處理的,這也是邊編譯邊處理的核心所在。

現(xiàn)在,讓我們來(lái)總結(jié)整理下:

復(fù)制代碼 代碼如下:

  step 1.  讀入第一個(gè)代碼塊。
  step 2.  做語(yǔ)法分析,有錯(cuò)則報(bào)語(yǔ)法錯(cuò)誤(比如括號(hào)不匹配等),并跳轉(zhuǎn)到step5。
  step 3.  對(duì)var變量和function定義做“預(yù)編譯處理”(永遠(yuǎn)不會(huì)報(bào)錯(cuò)的,因?yàn)橹唤馕稣_的聲明)。
  step 4.  執(zhí)行代碼段,有錯(cuò)則報(bào)錯(cuò)(比如變量未定義)。
  step 5.  如果還有下一個(gè)代碼段,則讀入下一個(gè)代碼段,重復(fù)step2。
  step6. 結(jié)束。

而根據(jù)HTML文檔流的執(zhí)行順序,需要在頁(yè)面元素渲染前執(zhí)行的js代碼應(yīng)該放在<body>前面的<script>代碼塊中,而需要在頁(yè)面元素加載完后的js放在</body>元素后面,body標(biāo)簽的onload事件是在最后執(zhí)行的。
復(fù)制代碼 代碼如下:

<script type="text/javascript">
    alert("first");
    function Fn(){
     alert("third");
    }
</script>
<body onload="Fn()">

</body>
<script type="text/javascript">
    alert("second");
</script>

 

相關(guān)文章

  • 基于JavaScript 下namespace 功能的簡(jiǎn)單分析

    基于JavaScript 下namespace 功能的簡(jiǎn)單分析

    前些天在剝離 百度隨心聽(tīng) 的播放器引擎時(shí),看到了一個(gè)namespace方法,覺(jué)得新奇,當(dāng)然只是對(duì)于我自己而言,我入門(mén)js不久,經(jīng)驗(yàn)尚淺
    2013-07-07
  • javascript的防抖和節(jié)流你了解嗎

    javascript的防抖和節(jié)流你了解嗎

    這篇文章主要為大家介紹了javascript的防抖和節(jié)流,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • Javascript核心讀書(shū)有感之詞法結(jié)構(gòu)

    Javascript核心讀書(shū)有感之詞法結(jié)構(gòu)

    這篇文章主要介紹了Javascript核心讀書(shū)有感之詞法結(jié)構(gòu),需要的朋友可以參考下
    2015-02-02
  • 詳解JavaScript棧內(nèi)存與堆內(nèi)存

    詳解JavaScript棧內(nèi)存與堆內(nèi)存

    這篇文章主要介紹了JavaScript棧內(nèi)存與堆內(nèi)存,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • JavaScript Math.ceil 方法(對(duì)數(shù)值向上取整)

    JavaScript Math.ceil 方法(對(duì)數(shù)值向上取整)

    js Math.ceil用于對(duì)數(shù)值向上取整,即得到大于或等于該數(shù)值的最小整數(shù),需要的朋友可以參考下
    2015-01-01
  • easyui validatebox驗(yàn)證

    easyui validatebox驗(yàn)證

    這篇文章主要介紹了easyui validatebox驗(yàn)證,需要的朋友可以參考下
    2016-04-04
  • 探尋Javascript執(zhí)行效率問(wèn)題

    探尋Javascript執(zhí)行效率問(wèn)題

    作為開(kāi)發(fā)人員,Web頁(yè)面加載或刷新的速度對(duì)其網(wǎng)站至關(guān)重要。開(kāi)發(fā)人員在各種瀏覽器中調(diào)試JavaScript的方法要少得多。比如,在Mozilla Firefox中,可以使用Firebug調(diào)試JavaScript,但仍然不能調(diào)整很多性能問(wèn)題,如瀏覽器呈現(xiàn)消耗時(shí)間。
    2014-11-11
  • TypeScript開(kāi)發(fā)環(huán)境安裝

    TypeScript開(kāi)發(fā)環(huán)境安裝

    這篇文章介紹了TypeScript開(kāi)發(fā)環(huán)境的安裝方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • JavaScript 對(duì)話(huà)框和狀態(tài)欄使用說(shuō)明

    JavaScript 對(duì)話(huà)框和狀態(tài)欄使用說(shuō)明

    平時(shí)工作中,無(wú)論是調(diào)試 javascript 代碼還是進(jìn)行頁(yè)面提示,我們都會(huì)經(jīng)常使用 javascript 的對(duì)話(huà)框。除了創(chuàng)建明確不使用狀態(tài)欄的瀏覽器窗口,每個(gè)瀏覽器窗口的底部都有一個(gè)狀態(tài)欄,用來(lái)向用戶(hù)顯示一些特定的消息。
    2009-10-10

最新評(píng)論