<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          JS----預編譯及變量提升詳解

          2019-11-18    seo達人

          JS----預編譯及變量提升詳解

          JS屬于解釋型語言,在執行過程中順序執行,但是會分塊先預編譯然后才執行。因此在JS中存在一種變量提升的現象。搞懂預編譯環節,變量提升自然而然也就懂了。本文講圍繞以下幾點進行介紹(變量提升會穿插在其中講解):



          預編譯執行步驟

          示例演示



          預編譯執行步驟

          預編譯發生在函數執行的前一刻,過程如下:



          創建AO對象,執行期上下文(后面更新關于執行期上下文詳解)。

          尋找函數的形參和變量聲明,將變量和形參名作為AO對象的屬性名,值設定為undefined.

          將形參和實參相統一,即更改形參后的undefined為具體的形參值。

          尋找函數中的函數聲明,將函數名作為AO屬性名,值為函數體。



          至此,預編譯環節結束,函數中咯變量按照最終AO對象中的值開始執行。接下來,結合示例演示就會更加清晰。



          作者:北海北方

          鏈接:https://juejin.im/post/5aa6693df265da23884cb571

          來源:掘金

          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。



          示例演示

          我們先來看下面這段代碼:

          function fn(a){

          console.log(a);

          var a = 123;

          console.log(a);



              function a(){};

              console.log(a);

              

              var b = function(){};

              console.log(b);

              

              function d(){};

           }

           

           //調用函數

           fn(1);



          作者:北海北方

          鏈接:https://juejin.im/post/5aa6693df265da23884cb571

          來源:掘金

          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

          接下來我們來按照前面的步驟詳細分析它的預編譯執行過程:



          創建AO對象



          AO{

              //空對象    

          }

          復制代碼

          找形參和變量聲明



          AO{

              a : undefined,

              b : undefined

          }

          復制代碼

          形參和實參相統一



          AO{

              a : 1,

              b : undefined

          }

          復制代碼

          找函數聲明



          AO{

              a : function a(){},

              b : undefined,

              d : function d(){}

          }

          復制代碼預編譯環節就此結束,此時的AO對象已經更新為:

          AO{

              a : function a(){},

              b : undefined,

              d : function d(){}

          }

          復制代碼函數開始逐行順序執行:

           function fn(a){

              console.log(a);// 輸出functiona(){}

              var a = 123;//執行到這里重新對a賦,AO對象再一次更新

              console.log(a);// 輸出123

              

              function a(){};//預編譯環節已經進行了變量提升,故執行時不在看這行代碼

              console.log(a);// 輸出123

              

              var b = function(){};//這個是函數表達式不是函數聲明,故不能提升,會對AO中的b重新賦值

              console.log(b);//輸出function(){}

              

              function d(){};

           }

          復制代碼至此,函數執行完畢,銷毀AO對象。

          我們再來看幾個例子,熟悉函數的預編譯過程。

          示例一:

          function test (a,b){

              console.log(a);

              c = 0;

              var c;

              a = 3;

              b = 2;

              console.log(b);

              function b(){};

              function d(){};

              console.log(b);



          //調用函數

          test(1);

          復制代碼它的AO創建過程如下(此處省略創建空AO對象的部分,下文同):

          AO1{

              a : undefined,

              b : undefined,

              c : undefined

          }



          AO2{

              a : 1,

              b : undefined,

              c : undefined

          }



          AO3{

              a : 1,

              b : function b(){},

              c : undefined,

              d : function d(){}

          }

          復制代碼至此預編譯環節完成,開始執行:

          function test (a,b){

              console.log(a); //輸出1

              c = 0; //給AO對象中的c重新賦值0

              var c;//預編譯環節變量提升,不再讀此行代碼

              a = 3;//給AO對象中的a重新賦值3

              b = 2;//給AO對象中的b重新賦值2

              console.log(b);//輸出2

              function b(){};//預編譯環節變量提升,執行時不再讀這行代碼

              function d(){};//預編譯環節變量提升,執行時不再讀這行代碼

              console.log(b);//輸出2



          //調用函數

          test(1);



          復制代碼示例二:

          這個例子中我們引入全局對象GO。GO與AO的過程類似

          function test(){

          var a = b = 123;

          }

          test();

          復制代碼此函數的執行過程:先把123賦給b,再聲明a,再把b賦給a。此時變量b未經聲明就賦值,為全局變量。預編譯環節如下:

          GO1{

          b : undefined

          }

          AO1{

          a : undefined

          }



          GO2{

              b : 123;

          }

          AO2{

              a : 123;

          }

          復制代碼示例三 :

          console.log(test);

          function test(test){

             console.log(test);

             var test = 234;

             console.log(test);

             function test(){};

          }

          test(1);

          var test = 123;

          復制代碼我們來看它的預編譯過程:

          //執行前(頁面加載完成時)生成GO對象

          GO1{

              test : undefined

          }

          GO2{

              test : function(){}

          }



          //輸出 function test(){...}



          //執行test()前生成它的AO對象

          AO1{

              test : undefined

          }

          AO2{

              test : 1

          }

          AO3{

              test : function test(){}

          }



          //預編譯結束開始執行test(1);

          AO4{

              test : 234

          }

          //輸出234

          復制代碼示例四:

          function demo(){

              console.log(b);

              if(a){

                  var b = 100;

              }

              console.log(b);

              c = 234;

              console.log(c);

          }

          var a;

          demo();

          a = 10;

          console.log(c);

          復制代碼我們來看它的預編譯過程:

          //首先是全局對象GO 

          GO1{

              a : undefined

          }

          G02{

              a : undefined,

              demo : function demo(){}

          }

          //執行demo()前預編譯,由于demo中的c未聲明就使用故為全局對象



          //輸出undefined

          GO3{

              a : undefined,

              demo : function demo(){}

              c : undefined

          }

          //此時a還是undefined,故不執行if()代碼塊

          //輸出還是undefined

          GO4{

              a : undefined,

              demo : function demo(){}

              c : 234;

          }

          //輸出234

          GO5{

              a : 10,

              demo : function demo(){}

              c : 234;

          }

          //輸出234


          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合