九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
!!!JS的預(yù)編譯和執(zhí)行順序 詳析(及全局與局部變量)

最近在復(fù)習(xí)javascript的事件處理時(shí)發(fā)現(xiàn)了一個(gè)問(wèn)題,于是總結(jié)一下:javascript的預(yù)編譯和執(zhí)行順序的問(wèn)題:

 
<html>  <head>    <title>事件處理</title>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <script type='text/javascript'>        //頁(yè)面在在完成加載后        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;
alert( j=i>3);//全true
 } i
++; input=input.parentNode; } } </script> </head> <body> <div> <input type='button' value='Event事件' id='button' /> <p id='p'>事件捕獲的順序:</p> </div> </body></html>

第一次調(diào)用,引用的也是i最后的值6
事件捕獲的順序:

(6) INPUT
(6) DIV
(6) BODY
(6) HTML
(6) #document

當(dāng)我更改了代碼中紅色的部分后得到的結(jié)果又不相同:

<html>  <head>    <title>事件處理</title>    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>    <script type='text/javascript'>        //頁(yè)面在在完成加載后        window.onload=function(){            var input=document.getElementById('button');            var p=document.getElementById('p');            var i=1;            while(input){                input.onclick=function(){
//修改成++i 也類似
p.innerHTML
+='<br />('+ i++ +') '+this.nodeName
alert( j=i>3);//有false 有true
  } input
=input.parentNode; } } </script> </head> <body> <div> <input type='button' value='Event事件' id='button' /> <p id='p'>事件捕獲的順序:</p> </div> </body></html>
第一次onclick引用時(shí)i=1,引用過(guò)程中加了1,第二次引用時(shí)i=2.

事件捕獲的順序:
(1) INPUT
(2) DIV
(3) BODY
(4) HTML
(5) #document


于是,得出這兩種不同的結(jié)果那是因?yàn)閖avascript代碼在運(yùn)行時(shí)有預(yù)編譯和執(zhí)行兩個(gè)階段,在預(yù)編譯階段會(huì)對(duì)函數(shù)和變量進(jìn)行處理,對(duì)所有的聲明變量會(huì)賦值為underfined,對(duì)所有的聲明函數(shù)也會(huì)賦值為函數(shù)的定義。
 
下面我們來(lái)測(cè)試javascript的執(zhí)行過(guò)程
 
1.javascript代碼執(zhí)行順序時(shí)按照腳本標(biāo)簽<script>出現(xiàn)的順序來(lái)確定的,瀏覽下面頁(yè)面你會(huì)發(fā)現(xiàn)代碼是按從上到下的順序執(zhí)行的
<script type='text/javascript'>    alert('one');  </script>  <script type='text/javascript'>  alert('two');  </script>  <script type='text/javascript'>  alert('three');  </script>

 

2. 因?yàn)樽兞吭陬A(yù)編譯時(shí)被賦予一個(gè)undefined初值,所以下面代碼中,第一個(gè)變量name在代碼中沒有被賦值,所有就延用undefined這個(gè)值,下面的name被賦予了Jude,所以第二次輸出的是Jude這個(gè)字符。
<script type='text/javascript'>    alert(name);                    //顯示undefined    var name='Jude';    alert(name);                    //顯示Jude</script>
  3.從如下結(jié)果中我們知道先是連續(xù)兩次輸出Hello Wrold!,最后連續(xù)兩次輸出test,得出這樣的結(jié)果是因?yàn)閖avascript并非是完全按照順序執(zhí)行的,而是在執(zhí)行之前先進(jìn)行一個(gè)預(yù)編譯,預(yù)編譯 時(shí)聲明式函數(shù)被提取出來(lái),優(yōu)先執(zhí)行,而且相同的函數(shù)會(huì)進(jìn)行覆蓋,再執(zhí)行賦值式函數(shù)。
 
<script type='text/javascript'>    test();                    //輸出Hello World!    function test(){               alert('hello');     //聲明式函數(shù)    }    test();                    //輸出Hello World!     var test=function(){    //賦值式函數(shù)        alert('test');    }    test();                    //輸出test    function test(){      //聲明式函數(shù)        alert('Hello World!');    }    test();                    //輸出test</script>

 

  4.下面代碼顯示顯示hello,再顯示hello world!,這是因?yàn)閖avascript中的給個(gè)代碼塊是相互獨(dú)立的,當(dāng)腳本遇到第一個(gè)<script>標(biāo)簽時(shí),則javascript 解析器會(huì)等這個(gè)代碼塊加載完成后,先對(duì)它進(jìn)行預(yù)編譯,然后再執(zhí)行之,然后javascript解析器準(zhǔn)備解析下一個(gè)代碼塊,由于javascript是按 塊執(zhí)行的,所有一個(gè)javascript調(diào)用下一個(gè)塊的函數(shù)或者變量時(shí),會(huì)出現(xiàn)錯(cuò)誤
<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是按塊執(zhí)行的,但不同的塊卻屬于相同的全局作用域,不同的塊的變量和函數(shù)式可以相互使用的,也就是某個(gè)塊可以使用前面塊的變量和函數(shù),卻不可以使用它之后的塊的變量和函數(shù)
 
<script type='text/javascript'>    alert(name);                    //顯示undefined    var name='Jude';    function test(){        alert('hello');    }    fun();                            //不能調(diào)用下一個(gè)塊的函數(shù)</script><script type='text/javascript'>    alert(name);                    //可以調(diào)用上一個(gè)塊的變量,顯示Jude    test();                            //可以調(diào)用上一個(gè)塊的函數(shù),顯示hello    function fun(){        alert('fun');    }</script>

 

  6.javascript在預(yù)編譯階段是以函數(shù)來(lái)劃分作用域的,然后再通過(guò)var 聲明的變量來(lái)與聲明函數(shù)開辟內(nèi)存空間,對(duì)var變量賦初值undefined。在執(zhí)行階段再根據(jù)作用域來(lái)嘴變量進(jìn)行賦值.
 
  第一個(gè)代碼塊中函數(shù)里面的變量a是局部變量,因?yàn)閍在函數(shù)內(nèi)重新用var定義,所以輸出undefined,而變量b是全局變量,因?yàn)樵诤瘮?shù)內(nèi)沒有用var重新聲明b,所以在給變量b賦值時(shí)到全局變量中找全局變量b的值,所以輸出的是b.
 
  第二個(gè)代碼塊中的函數(shù)內(nèi)都重新聲明了變量a和b,所以他們都是函數(shù)內(nèi)的局部變量,所以都輸出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在執(zhí)行時(shí)的步驟是:
 
    1、先讀入第一段代碼塊
 
    2、對(duì)代碼塊進(jìn)行語(yǔ)法分析,如果出現(xiàn)語(yǔ)法錯(cuò)誤,直接執(zhí)行第5步驟
 
    3、對(duì)var變量和function定義的函數(shù)進(jìn)行“預(yù)編譯處理”(賦值式函數(shù)是不會(huì)進(jìn)行預(yù)編譯處理的)
 
    4、執(zhí)行代碼塊,有錯(cuò)則報(bào)錯(cuò)
 
    5、如果還有下一段代碼塊,則讀入下一段代碼塊,重復(fù)步驟2
 
    6、結(jié)束
 然后,再說(shuō)說(shuō)全局變量和局部變量。直接看代碼:
<script type="text/javascript">   var a = "Hello";   function test(){        var a;        alert(a);        a = "World";        alert(a);   }  </script> 

 

<script type="text/javascript">   var a = "Hello";   function test(){        alert(a);        a = "World";        alert(a);   }  </script> 

 


這個(gè)就是全局變量跟局部變量的scope問(wèn)題嗎?我說(shuō):"當(dāng)全局變量跟局部變量重名時(shí),局部變量的scope會(huì)覆蓋掉全局變量的 scope,當(dāng)離開局部變量的scope后,又重回到全局變量的scope。所以兩段代碼運(yùn)行的結(jié)果分別為:1) undefined World 2) Hello World。然后我隨意編了如下一個(gè)例子給她:

    <script>         var a =1;         function test(){            alert(a);            var a = 2;            alert(a);         }         test();         alert(a);      </script>  

 

        大家猜結(jié)果等于多少?是輸出1 2 1 嗎?嗯嗯,當(dāng)我把測(cè)試case發(fā)給她之前也是這么認(rèn)為的,但測(cè)試輸出后……運(yùn)行結(jié)果是 undefined 2 1。當(dāng)時(shí)百思不得其解,問(wèn)了谷老師才知道,我對(duì)JS還不是非常了解,所以痛下苦功,學(xué)習(xí)+測(cè)試,總結(jié)如下:

        一、Javascript的變量的scope是根據(jù)方法塊來(lái)劃分的(也就是說(shuō)以function的一對(duì)大括號(hào){ }來(lái)劃分)。切記,是function塊,而for、while、if塊并不是作用域的劃分標(biāo)準(zhǔn),可以看看以下幾個(gè)例子:

 

    <script>      function test2(){          alert ("before for scope:"+i);    // i未賦值(并不是未聲明!使用未聲明的變量或函數(shù)全拋出致命錯(cuò)誤而中斷腳本執(zhí)行)                                                                // 此時(shí)i的值是underfined          for(var i=0;i<3;i++){              alert("in for scope:"+i);  // i的值是 0、1、2, 當(dāng)i為3時(shí)跳出循環(huán)          }          alert("after for scope:"+i);  // i的值是3,注意,此時(shí)已經(jīng)在for scope以外,但i的值仍然保留為3                    while(true){              var j = 1;              break;          }          alert(j);    // j的值是1,注意,此時(shí)已經(jīng)在while scope以外,但j的值仍然保留為1                if(true){              var k = 1;          }          alert(k);  //k的值是1,注意,此時(shí)已經(jīng)在if scope以外,但k的值仍然保留為1      }            test2();      //若在此時(shí)(function scope之外)再輸出只存在于test2 這個(gè)function scope里的 i、j、k變量會(huì)發(fā)生神馬效果呢?      alert(i); //error! 沒錯(cuò),是error,原因是變量i未聲明(并不是未賦值,區(qū)分test2函數(shù)的第一行輸出),導(dǎo)致腳本錯(cuò)誤,程序到此結(jié)束!      alert("這行打印還會(huì)輸出嗎?"); //未執(zhí)行      alert(j); //未執(zhí)行      alert(k); //未執(zhí)行      </script>  

 

        二、Javascript在執(zhí)行前會(huì)對(duì)整個(gè)腳本文件的聲明部分做完整分析(包括局部變量),從而確定實(shí)變量的作用域。怎么理解呢?看下面一個(gè)例子:

    <script>          var a =1;          function test(){              alert(a); //a為undefined! 這個(gè)a并不是全局變量,這是因?yàn)樵趂unction scope里已經(jīng)聲明了(函數(shù)體倒數(shù)第4行)一個(gè)重名的局部變量,                           //所以全局變量a被覆蓋了,這說(shuō)明了Javascript在執(zhí)行前會(huì)對(duì)整個(gè)腳本文件的定義部分做完整分析,所以在函數(shù)test()執(zhí)行前,                           //函數(shù)體中的變量a就被指向內(nèi)部的局部變量.而不是指向外部的全局變量. 但這時(shí)a只有聲明,還沒賦值,所以輸出undefined。              a=4                     alert(a);  //a為4,沒懸念了吧? 這里的a還是局部變量哦!              var a;     //局部變量a在這行聲明              alert(a);  //a還是為4,這是因?yàn)橹耙寻?賦給a了          }          test();          alert(a); //a為1,這里并不在function scope內(nèi),a的值為全局變量的值      </script>  

 

        三,當(dāng)全局變量跟局部變量重名時(shí),局部變量的scope會(huì)覆蓋掉全局變量的scope,當(dāng)離開局部變量的scope后,又重回到全局變量的scope,而 當(dāng)全局變量遇上局部變量時(shí),怎樣使用全局變量呢?用window.globalVariableName。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Javascript:談?wù)凧S的全局變量跟局部變量
JavaScript(1) -- JS入門
Javascript預(yù)編譯和執(zhí)行過(guò)程
淺談JavaScript編程語(yǔ)言的編碼規(guī)范
前端教程:JavaScript變量和數(shù)據(jù)類型
javascript的全局變量和局部變量 | 前端開拓者
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服