javascript的預編譯和執行順序

   最近在複習javascript的事件處理時發現了一個問題,而後也是我來寫javascript的預編譯和執行順序的問題javascript

  代碼:html

代碼一
<html> <head> <title>事件處理</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <script type='text/javascript'> //頁面在在完成加載後 window.onload=function(){ var input=document.getElementById('button'); var p=document.getElementById('p'); var i=1; while(input){ input.onclick=function(){ p.innerHTML+='<br />('+ i +') '+this.nodeName; } i++; input=input.parentNode; } } </script> </head> <body> <div> <input type='button' value='Event事件' id='button' /> <p id='p'>事件捕獲的順序:</p> </div> </body> </html>

 顯示的結果爲:java

                     

當我更改了代碼中紅色的部分後獲得的結果又不相同:node

代碼二
<html> <head> <title>事件處理</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <script type='text/javascript'> //頁面在在完成加載後 window.onload=function(){ var input=document.getElementById('button'); var p=document.getElementById('p'); var i=1; while(input){ input.onclick=function(){ p.innerHTML+='<br />('+ i++ +') '+this.nodeName; } input=input.parentNode; } } </script> </head> <body> <div> <input type='button' value='Event事件' id='button' /> <p id='p'>事件捕獲的順序:</p> </div> </body> </html>

獲得的結果爲:函數

            

  得出這兩種不一樣的結果那是由於javascript代碼在運行時有預編譯和執行兩個階段,在預編譯階段會對函數和變量進行處理,對全部的聲明變量會賦值爲underfined,對全部的聲明函數也會賦值爲函數的定義。測試

  下面咱們來測試javascript的執行過程ui

  1.javascript代碼執行順序時按照腳本標籤<script>出現的順序來肯定的,瀏覽下面頁面你會發現代碼是按從上到下的順序執行的this

<script type='text/javascript'>
    alert('one');
  </script>
  <script type='text/javascript'>
  alert('two');
  </script>
  <script type='text/javascript'>
  alert('three');
  </script>

   2. 由於變量在預編譯時被賦予一個undefined初值,因此下面代碼中,第一個變量name在代碼中沒有被賦值,全部就延用undefined這個值,下面的name被賦予了Jude,因此第二次輸出的是Jude這個字符。spa

<script type='text/javascript'>
    alert(name);                    //顯示undefined
    var name='Jude';
    alert(name);                    //顯示Jude
</script>

  3.從以下結果中咱們知道先是連續兩次輸出Hello Wrold!,最後連續兩次輸出test,得出這樣的結果是由於javascript並不是是徹底按照順序執行的,而是在執行以前先進行一個預編譯,預編譯時聲明式函數被提取出來,優先執行,並且相同的函數會進行覆蓋,再執行賦值式函數。code

<script type='text/javascript'>
    test();                    //輸出Hello World!
    function test(){       
        alert('hello');     //聲明式函數 }
    test();                    //輸出Hello World!

    var test=function(){    //賦值式函數
        alert('test');
    }
    test();                    //輸出test
    function test(){      //聲明式函數
        alert('Hello World!');
    }
    test();                    //輸出test
</script>

  4.下面代碼顯示顯示hello,再顯示hello world!,這是由於javascript中的給個代碼塊是相互獨立的,當腳本遇到第一個<script>標籤時,則javascript解析器會等這個代碼塊加載完成後,先對它進行預編譯,而後再執行之,而後javascript解析器準備解析下一個代碼塊,因爲javascript是按塊執行的,全部一個javascript調用下一個塊的函數或者變量時,會出現錯誤

<script type='text/javascript'>
    function test(){
        alert('hello');                //顯示hello
    }
    test()
</script>
<script type='text/javascript'>
    function test(){
        alert('hello world!');        //顯示hello world!
    }
    test()
</script>

  5.雖然javascript是按塊執行的,但不一樣的塊卻屬於相同的全局做用域,不一樣的塊的變量和函數式能夠相互使用的,也就是某個塊能夠使用前面塊的變量和函數,卻不能夠使用它以後的塊的變量和函數

<script type='text/javascript'>
    alert(name);                    //顯示undefined
    var name='Jude';
    function test(){
        alert('hello');
    }
    fun();                            //不能調用下一個塊的函數
</script>
<script type='text/javascript'>
    alert(name);                    //能夠調用上一個塊的變量,顯示Jude
    test();                            //能夠調用上一個塊的函數,顯示hello
    function fun(){
        alert('fun');
    }
</script>

  6.javascript在預編譯階段是以函數來劃分做用域的,而後再經過var 聲明的變量來與聲明函數開闢內存空間,對var變量賦初值undefined。在執行階段再根據做用域來嘴變量進行賦值.

  第一個代碼塊中函數裏面的變量a是局部變量,由於a在函數內從新用var定義,因此輸出undefined,而變量b是全局變量,由於在函數內沒有用var從新聲明b,因此在給變量b賦值時到全局變量中找全局變量b的值,因此輸出的是b.

  第二個代碼塊中的函數內都從新聲明瞭變量a和b,因此他們都是函數內的局部變量,因此都輸出undefined。

<script type='text/javascript'>
    var a='a';
    var b='b';
    function test(){
        alert(a);                //顯示undefined
        alert(b);                //顯示b
        var a='test';
    }
    test();
</script>
<script type='text/javascript'>
    var a='a';                    
    var b='b';                    
    function test(){
        alert(a);                //顯示undefined
        alert(b);                //顯示undefined
        var a='test';
        var b='test';
    }
    test();
</script>

  綜上所述,javascript在執行時的步驟是:

    一、先讀入第一段代碼塊

    二、對代碼塊進行語法分析,若是出現語法錯誤,直接執行第5步驟

    三、對var變量和function定義的函數進行「預編譯處理」(賦值式函數是不會進行預編譯處理的)

    四、執行代碼塊,有錯則報錯

    五、若是還有下一段代碼塊,則讀入下一段代碼塊,重複步驟2

    六、結束

相關文章
相關標籤/搜索