国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript-變量提升(AO、GO)編譯、閉包

plokmju88 / 3050人閱讀

摘要:是一個解釋型語言上明確的說,是一個輕量級的解釋型的面向對象的將函數視為一級公民的語言。全局代碼在執行的時候,先是變量提升,在全局作用域內添加屬性,然后是函數以函數聲明創建的函數提升,再是代碼執行。那么,很顯然,閉包其實就是一個函數。

JavaScript是一個解釋型語言

MDN上明確的說,JavaScript是一個輕量級的、解釋型的、面向對象的、將函數視為一級公民的語言。
那么,既然js是一個解釋型語言,那它就是在運行時把代碼轉換成機器可以識別的語言。哪它又為什么會存在變量提升呢?
下面這篇文章給出了解釋,在此也特別感謝作者的分享!
https://mp.weixin.qq.com/s/ne...

變量提升、預編譯過程
function fn(c){
    console.log(c);  //true
    var c = false;
    console.log(a);  //function a(){}
    var a = 1;
    console.log(a);  //1
    function a(){
        
    };
    console.log(a);  //1
    b();             //函數聲明
    var b = function(){
        console.log("函數表達式");
    }
    function b(){    
        console.log( "函數聲明" )
    }
    b();             //函數表達式
    var d = 4;
}
fn(true);

上面這個fn方法很簡單,相信很多人都能過做出來,但肯定也很多人不理解結果為什么是這樣!
那么這個過程是怎樣執行的呢:
首先,js在執行前會產生一個GO(Global Object),也就是我們常說的全局作用域。當一個方法被調用的時候會形成一個局部作用域AO(Activation Object)。
全局代碼在執行的時候,先是變量提升,在全局作用域內添加屬性,然后是函數(以函數聲明創建的函數)提升,再是代碼執行。
函數在被調用的時候,以上面的fn這個方法為例,進入函數上下文,但是在執行代碼之前,經歷的階段:
第一階段:首先創建一個AO,并包含下列屬性:

AO : {
    arguments: ,  //函數內部參數的類數組對象
    c: true,            //傳入的參數,如果沒有傳遞實參,那么值就是undefined
}

第二階段:函數內部的函數(以函數聲明創建的函數)提升

AO : {
    arguments: ,
    c: true,
    a: function a(){},
    b: function b(){ console.log( "函數聲明" ) }
}

第三階段:函數內部的變量提升

AO : {
    arguments: ,
    c: true,
    a: function a(){},
    b: function b(){ console.log( "函數聲明" ) },
    d: undefined
}

函數內部又定義了變量 var c和var a,當變量提升時,發現AO中已經存在a和c屬性,如果變量名稱跟已經聲明的形參或函數相同,則變量聲明不會干擾已經存在的這類屬性。如果不相同切不存在,那就會放到AO中,值為undefined。

當上面的這些準備工作做完之后,才會開始執行函數內部的代碼,這樣就很好明白,函數內部的變量,在什么階段分別代表什么樣的值!

閉包解析

在JavaScript高級程序3中,對閉包的描述是這樣的,閉包是指有權訪問另一個函數作用域中的變量的函數。那么,很顯然,閉包其實就是一個函數。
那么我們怎樣通過GO、AO理解閉包呢:

function foo(){
    var a = 1;
    function fnSon(){
        a++;
        console.log(a);
    }
    return fnSon;
}
var fnTest = foo();
fnTest();   //2
fnTest();   //3

當foo這個方法被調用的時候,創建一個AO,當函數執行完之后AO里面包含了變量a、函數fnSon

AO:{
    a:1,
    fnSon: function(){}
}

此時的fnSon被賦值給了fnTest,那么foo方法的AO在執行完之后就沒辦法被銷毀,當fnTest被調用的時候,代碼執行完之后,foo的AO對象中的a變成了2,再次調用fnTest的時候就變成3。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106270.html

相關文章

  • js預編譯過程

    摘要:所以變量聲明提升和函數聲明提升會出現一個先后順序預編譯過程結束。 先科普: 1.javaScript是解釋型語言,就是編譯一行,執行一行.....2.javaScript沒有塊級及作用域......3.javaScript具有變量和函數聲明提升功能.....4.AO對象和GO對象....5.預編譯就是解決代碼執行順序問題,與java語言類似(jvm).... 例如: (function...

    FWHeart 評論0 收藏0
  • 5分鐘讀懂JavaScript編譯流程

    摘要:大家都知道是解釋型語言,既然是解釋型語言,就是編譯一行,執行一行,那又何來預編譯一說呢腳本執行引擎都做了什么呢今天我們就來看看吧。全局域就是一切聲明的全局變量,全是的屬性等同于函數預編譯發生在函數執行前一刻。 大家都知道JavaScript是解釋型語言,既然是解釋型語言,就是編譯一行,執行一行,那又何來預編譯一說呢?腳本執行js引擎都做了什么呢?今天我們就來看看吧。 1-JavaScr...

    Baoyuan 評論0 收藏0
  • JavaScript的預編譯過程與作用域

    摘要:詞法作用域是一種靜態作用域這個例子的結果按靜態作用域來分析執行函數,先從函數內部查找是否有局部變量,如果沒有,就根據書寫的位置,查找上面一層的代碼,也就是等于,所以結果會打印。靜態作用域,決定的是作用域鏈的順序。 博客原文地址:https://finget.github.io/2018/03/01/javascriptPrecompile/看不明白的地方歡迎提問,有理解的不對的地方希望...

    ziwenxie 評論0 收藏0
  • javascript作用域,作用域鏈,[[scope]]屬性

    摘要:正式由于作用域鏈的這種關系,我們就不難理解,為什么和不能通過作用域鏈向上搜索,因為對和的搜索在當前執行函數的活動對象就停止了。 對于Javascript程序員來說,閉包總會讓你覺得既熟悉又陌生,然而它對于開發人員來說卻非常重要,javascript里的許多設計模式中都用到了閉包,此處以函數作用域為例。 //示例代碼 var a=1; function foo(){ ...

    pkhope 評論0 收藏0
  • JavaScript的預編譯過程分析

    摘要:一概念是一個單線程解釋型的編程語言。預編譯大致可分為步創建對象找形參和變量聲明,將形參和變量名作為屬性名,值為將實參值和形參統一在函數體里面找函數聲明,值賦予函數體。 一、JavaScript概念 JavaScript ( JS ) 是一個單線程、解釋型的編程語言。 二、JavaScript語言特點 2.1 單線程 JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能...

    graf 評論0 收藏0

發表評論

0條評論

plokmju88

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<