最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

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

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

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

<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ù)。

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

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

     }

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

     }
</script>

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

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


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

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

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

<script type="text/javascript">
     Fn();  //執(zhí)行結(jié)果:"執(zhí)行了函數(shù)2",同名函數(shù)后者會覆蓋前者
     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);//瀏覽器報錯,但并沒有彈出信息窗
</script>
//代碼塊二
<script type="text/javascript">
      alert(str); //彈窗"undefined"
      var str = "aaa";
</script>
//js在預(yù)處理期對變量進行了聲明處理,但是并沒有進行初始化與賦值,所以導(dǎo)致代碼塊二中的變量是unfiened的,而代碼一中的變量是完全不存在的,所以瀏覽器報錯。

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

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

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

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

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

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

  step 1.  讀入第一個代碼塊。
  step 2.  做語法分析,有錯則報語法錯誤(比如括號不匹配等),并跳轉(zhuǎn)到step5。
  step 3.  對var變量和function定義做“預(yù)編譯處理”(永遠(yuǎn)不會報錯的,因為只解析正確的聲明)。
  step 4.  執(zhí)行代碼段,有錯則報錯(比如變量未定義)。
  step 5.  如果還有下一個代碼段,則讀入下一個代碼段,重復(fù)step2。
  step6. 結(jié)束。

而根據(jù)HTML文檔流的執(zhí)行順序,需要在頁面元素渲染前執(zhí)行的js代碼應(yīng)該放在<body>前面的<script>代碼塊中,而需要在頁面元素加載完后的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)文章

最新評論

满城县| 政和县| 沅陵县| 美姑县| 永济市| 湛江市| 乌海市| 靖江市| 无棣县| 同心县| 酉阳| 琼结县| 集贤县| 德州市| 西畴县| 根河市| 乌拉特中旗| 边坝县| 海盐县| 灵宝市| 郁南县| 犍为县| 高唐县| 北辰区| 闻喜县| 乌兰县| 花莲县| 台东市| 措勤县| 固原市| 南丰县| 大丰市| 丰城市| 武汉市| 耒阳市| 肇庆市| 中山市| 潼南县| 岳阳市| 德兴市| 三台县|