<strike id="cy2gs"><menu id="cy2gs"></menu></strike>
  • <del id="cy2gs"><dfn id="cy2gs"></dfn></del>
  • JS----預編譯及變量提升詳解

    2019-11-18    seo達人

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

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



    預編譯執(zhí)行步驟

    示例演示



    預編譯執(zhí)行步驟

    預編譯發(fā)生在函數(shù)執(zhí)行的前一刻,過程如下:



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

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

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

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



    至此,預編譯環(huán)節(jié)結束,函數(shù)中咯變量按照最終AO對象中的值開始執(zhí)行。接下來,結合示例演示就會更加清晰。



    作者:北海北方

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

    來源:掘金

    著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。



    示例演示

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

    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(){};

     }

     

     //調用函數(shù)

     fn(1);



    作者:北海北方

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

    來源:掘金

    著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。

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



    創(chuàng)建AO對象



    AO{

        //空對象    

    }

    復制代碼

    找形參和變量聲明



    AO{

        a : undefined,

        b : undefined

    }

    復制代碼

    形參和實參相統(tǒng)一



    AO{

        a : 1,

        b : undefined

    }

    復制代碼

    找函數(shù)聲明



    AO{

        a : function a(){},

        b : undefined,

        d : function d(){}

    }

    復制代碼預編譯環(huán)節(jié)就此結束,此時的AO對象已經(jīng)更新為:

    AO{

        a : function a(){},

        b : undefined,

        d : function d(){}

    }

    復制代碼函數(shù)開始逐行順序執(zhí)行:

     function fn(a){

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

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

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

        

        function a(){};//預編譯環(huán)節(jié)已經(jīng)進行了變量提升,故執(zhí)行時不在看這行代碼

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

        

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

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

        

        function d(){};

     }

    復制代碼至此,函數(shù)執(zhí)行完畢,銷毀AO對象。

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

    示例一:

    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);



    //調用函數(shù)

    test(1);

    復制代碼它的AO創(chuàng)建過程如下(此處省略創(chuàng)建空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(){}

    }

    復制代碼至此預編譯環(huán)節(jié)完成,開始執(zhí)行:

    function test (a,b){

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

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

        var c;//預編譯環(huán)節(jié)變量提升,不再讀此行代碼

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

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

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

        function b(){};//預編譯環(huán)節(jié)變量提升,執(zhí)行時不再讀這行代碼

        function d(){};//預編譯環(huán)節(jié)變量提升,執(zhí)行時不再讀這行代碼

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



    //調用函數(shù)

    test(1);



    復制代碼示例二:

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

    function test(){

    var a = b = 123;

    }

    test();

    復制代碼此函數(shù)的執(zhí)行過程:先把123賦給b,再聲明a,再把b賦給a。此時變量b未經(jīng)聲明就賦值,為全局變量。預編譯環(huán)節(jié)如下:

    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;

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

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

    GO1{

        test : undefined

    }

    GO2{

        test : function(){}

    }



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



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

    AO1{

        test : undefined

    }

    AO2{

        test : 1

    }

    AO3{

        test : function test(){}

    }



    //預編譯結束開始執(zhí)行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(){}

    }

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



    //輸出undefined

    GO3{

        a : undefined,

        demo : function demo(){}

        c : undefined

    }

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

    //輸出還是undefined

    GO4{

        a : undefined,

        demo : function demo(){}

        c : 234;

    }

    //輸出234

    GO5{

        a : 10,

        demo : function demo(){}

        c : 234;

    }

    //輸出234


    日歷

    鏈接

    個人資料

    藍藍設計的小編 http://www.skdbbs.com

    存檔

    主站蜘蛛池模板: 蜜臀AV无码国产精品色午夜麻豆| 亚洲精品动漫免费二区| 精品久人妻去按摩店被黑人按中出 | 牛牛在线精品观看免费正| 2022国内精品免费福利视频| 亚洲性日韩精品一区二区三区| 国内精品久久久久久麻豆 | 国产精品人人做人人爽| 国产精品无码成人午夜电影| 亚洲永久精品ww47| 久久午夜无码鲁丝片午夜精品| 中文精品一卡2卡3卡4卡| 中文字幕无码久久精品青草| HEYZO无码综合国产精品227| 久久亚洲国产精品五月天婷| 亚洲精品视频在线| 国内精品一级毛片免费看| 热re99久久精品国99热| 亚洲精品天堂成人片?V在线播放| 国产呦小j女精品视频| 国产精品第一区第27页| 夜色www国产精品资源站| 国内精品免费在线观看| 2022国内精品免费福利视频| 国产午夜精品无码| 久久亚洲私人国产精品vA| 中文字幕久久精品无码| 亚洲精品国产综合久久一线| 日韩精品无码永久免费网站| 欧美日韩精品系列一区二区三区| 久久精品国产一区二区三区| 国产亚洲精品不卡在线| 精品亚洲成α人无码成α在线观看| 国产精品亚洲玖玖玖在线观看| 国产精品麻豆VA在线播放| 国产精品伦理久久久久久| 精品人妻一区二区三区毛片| 久久久无码精品亚洲日韩软件| 欧洲精品一区二区三区在线观看| 人妻少妇精品无码专区动漫| 亚洲国产91精品无码专区|