javascript的先行編譯和執行順序

來源:互聯網
上載者:User

javascript的先行編譯和執行順序
 最近在複習javascript的事件處理時發現了一個問題,然後也是我來寫javascript的先行編譯和執行順序的問題   代碼: 複製代碼代碼一<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>複製代碼 顯示的結果為:                        當我更改了代碼中紅色的部分後得到的結果又不相同: 複製代碼代碼二<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的執行過程   1.javascript代碼執行順序時按照指令碼標籤<script>出現的順序來確定的,瀏覽下面頁面你會發現代碼是按從上到下的順序執行的 複製代碼<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這個字元。 <script type='text/javascript'>    alert(name);                    //顯示undefined    var name='Jude';    alert(name);                    //顯示Jude</script>  3.從如下結果中我們知道先是連續兩次輸出Hello Wrold!,最後連續兩次輸出test,得出這樣的結果是因為javascript並非是完全按照順序執行的,而是在執行之前先進行一個先行編譯,先行編譯時聲明式函數被提取出來,優先執行,而且相同的函數會進行覆蓋,再執行賦值式函數。 複製代碼<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在執行時的步驟是:     1、先讀入第一段代碼塊     2、對代碼塊進行文法分析,如果出現語法錯誤,直接執行第5步驟     3、對var變數和function定義的函數進行“先行編譯處理”(賦值式函數是不會進行先行編譯處理的)     4、執行代碼塊,有錯則報錯     5、如果還有下一段代碼塊,則讀入下一段代碼塊,重複步驟2     6、結束

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.