日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JS----预编译及变量提升详解

發(fā)布時(shí)間:2023/12/31 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS----预编译及变量提升详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

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

  • 預(yù)編譯執(zhí)行步驟
  • 示例演示

預(yù)編譯執(zhí)行步驟

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

  • 創(chuàng)建AO對(duì)象,執(zhí)行期上下文(后面更新關(guān)于執(zhí)行期上下文詳解)。
  • 尋找函數(shù)的形參和變量聲明,將變量和形參名作為AO對(duì)象的屬性名,值設(shè)定為undefined.
  • 將形參和實(shí)參相統(tǒng)一,即更改形參后的undefined為具體的形參值。
  • 尋找函數(shù)中的函數(shù)聲明,將函數(shù)名作為AO屬性名,值為函數(shù)體。
  • 至此,預(yù)編譯環(huán)節(jié)結(jié)束,函數(shù)中咯變量按照最終AO對(duì)象中的值開(kāi)始執(zhí)行。接下來(lái),結(jié)合示例演示就會(huì)更加清晰。

    示例演示

    我們先來(lái)看下面這段代碼:

    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(){};}//調(diào)用函數(shù)fn(1); 復(fù)制代碼

    接下來(lái)我們來(lái)按照前面的步驟詳細(xì)分析它的預(yù)編譯執(zhí)行過(guò)程:

  • 創(chuàng)建AO對(duì)象
  • AO{//空對(duì)象 } 復(fù)制代碼
  • 找形參和變量聲明
  • AO{a : undefined,b : undefined } 復(fù)制代碼
  • 形參和實(shí)參相統(tǒng)一
  • AO{a : 1,b : function(){} } 復(fù)制代碼
  • 找函數(shù)聲明
  • AO{a : function a(){},b : undefined,d : function d(){} } 復(fù)制代碼

    預(yù)編譯環(huán)節(jié)就此結(jié)束,此時(shí)的AO對(duì)象已經(jīng)更新為:

    AO{a : function a(){},b : undefined,d : function d(){} } 復(fù)制代碼

    函數(shù)開(kāi)始逐行順序執(zhí)行:

    function fn(a){console.log(a);// 輸出functiona(){}var a = 123;//執(zhí)行到這里重新對(duì)a賦,AO對(duì)象再一次更新console.log(a);// 輸出123function a(){};//預(yù)編譯環(huán)節(jié)已經(jīng)進(jìn)行了變量提升,故執(zhí)行時(shí)不在看這行代碼console.log(a);// 輸出123var b = function(){};//這個(gè)是函數(shù)表達(dá)式不是函數(shù)聲明,故不能提升,會(huì)對(duì)AO中的b重新賦值console.log(b);//輸出function(){}function d(){};} 復(fù)制代碼

    至此,函數(shù)執(zhí)行完畢,銷毀AO對(duì)象。

    我們?cè)賮?lái)看幾個(gè)例子,熟悉函數(shù)的預(yù)編譯過(guò)程。

    示例一:

    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); } //調(diào)用函數(shù) test(1); 復(fù)制代碼

    它的AO創(chuàng)建過(guò)程如下(此處省略創(chuàng)建空AO對(duì)象的部分,下文同):

    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(){} } 復(fù)制代碼

    至此預(yù)編譯環(huán)節(jié)完成,開(kāi)始執(zhí)行:

    function test (a,b){console.log(a); //輸出1c = 0; //給AO對(duì)象中的c重新賦值0var c;//預(yù)編譯環(huán)節(jié)變量提升,不再讀此行代碼a = 3;//給AO對(duì)象中的a重新賦值3b = 2;//給AO對(duì)象中的b重新賦值2console.log(b);//輸出2function b(){};//預(yù)編譯環(huán)節(jié)變量提升,執(zhí)行時(shí)不再讀這行代碼function d(){};//預(yù)編譯環(huán)節(jié)變量提升,執(zhí)行時(shí)不再讀這行代碼console.log(b);//輸出2 } //調(diào)用函數(shù) test(1); 復(fù)制代碼

    示例二:

    這個(gè)例子中我們引入全局對(duì)象GO。GO與AO的過(guò)程類似

    function test(){var a = b = 123; } test(); 復(fù)制代碼

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

    GO1{b : undefined } AO1{a : undefined }GO2{b : 123; } AO2{a : 123; } 復(fù)制代碼

    示例三 :

    console.log(test); function test(test){console.log(test);var test = 234;console.log(test);function test(){}; } test(1); var test = 123; 復(fù)制代碼

    我們來(lái)看它的預(yù)編譯過(guò)程:

    //執(zhí)行前(頁(yè)面加載完成時(shí))生成GO對(duì)象 GO1{test : undefined } GO2{test : function(){} }//輸出 function test(){...}//執(zhí)行test()前生成它的AO對(duì)象 AO1{test : undefined } AO2{test : 1 } AO3{test : function test(){} }//預(yù)編譯結(jié)束開(kāi)始執(zhí)行test(1); AO4{test : 234 } //輸出234 復(fù)制代碼

    示例四:

    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); 復(fù)制代碼

    我們來(lái)看它的預(yù)編譯過(guò)程:

    //首先是全局對(duì)象GO GO1{a : undefined } G02{a : undefined,demo : function demo(){} } //執(zhí)行demo()前預(yù)編譯,由于demo中的c未聲明就使用故為全局對(duì)象//輸出undefined GO3{a : undefined,demo : function demo(){}c : undefined } //此時(shí)a還是undefined,故不執(zhí)行if()代碼塊 //輸出還是undefined GO4{a : undefined,demo : function demo(){}c : 234; } //輸出234 GO5{a : 10,demo : function demo(){}c : 234; } //輸出234 復(fù)制代碼

    總結(jié)

    以上是生活随笔為你收集整理的JS----预编译及变量提升详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。