位置:首頁(yè) > 軟件操作教程 > 編程開發(fā) > JavaScript > 問(wèn)題詳情

JavaScript 定義閉包

提問(wèn)人:劉團(tuán)圓發(fā)布時(shí)間:2020-11-25

■知識(shí)點(diǎn)

    函數(shù)被調(diào)用時(shí),會(huì)產(chǎn)生一個(gè)臨時(shí)上下文活動(dòng)對(duì)象,它是函數(shù)作用域的頂級(jí)對(duì)象,作用域內(nèi)所有私有變量、參數(shù)、私有函數(shù)等都將作為上下文活動(dòng)對(duì)象的屬性而存在。

    函數(shù)被調(diào)用后,在默認(rèn)情況下上下文活動(dòng)對(duì)象會(huì)被立即釋放,避免占用系統(tǒng)資源。但是,當(dāng)函數(shù)內(nèi)的私有變量、參數(shù)、私有函數(shù)等被外界引用,則這個(gè)上下文活動(dòng)對(duì)象暫時(shí)會(huì)繼續(xù)存在,直到所有外界引用被注銷。

    但是,函數(shù)作用域是封閉的,外#無(wú)法訪問(wèn)。那么在什么情況下,外界可以訪問(wèn)到函數(shù)內(nèi)的私有成員呢?

    根據(jù)作用域鏈,內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)的私有成員。如果內(nèi)部函數(shù)引用了外部函數(shù)的私有成員,同時(shí)內(nèi)部函數(shù)又被傳給外界,或者對(duì)外界開放,那么閉包體就形成了。這個(gè)外部函數(shù)就是一個(gè)閉包體,它被調(diào)用后,它的調(diào)動(dòng)對(duì)象暫時(shí)不被注銷,其屬性會(huì)繼續(xù)存在,通過(guò)內(nèi)部函數(shù),可以持續(xù)讀寫外部函數(shù)的私有成員。

■實(shí)例設(shè)計(jì)

    典型的閉包體是一個(gè)嵌套結(jié)構(gòu)的函數(shù)。內(nèi)部函數(shù)引用外部函數(shù)的私有成員,同時(shí)內(nèi)部函數(shù)又被外界引用,當(dāng)外部函數(shù)被調(diào)用后,就形成了閉包,這個(gè)函數(shù)也稱為閉包函數(shù)。

下面是一個(gè)典型的閉包結(jié)構(gòu)。

function f(x){                       //外部函數(shù)

    returnfunction(y){               //內(nèi)部函數(shù),通過(guò)返回內(nèi)部函數(shù),實(shí)現(xiàn)外部引用

        return x + y;                //訪問(wèn)外部函數(shù)的參數(shù)

    };

}

var c = f (5);                      //調(diào)用外部函數(shù),獲取引用內(nèi)部函數(shù)

console.log(c(6));                  //調(diào)用內(nèi)部函數(shù),原外部函數(shù)的參數(shù)繼續(xù)存在

解析過(guò)程簡(jiǎn)單描述如下。

第1步,在JavaScript腳本預(yù)編譯期,聲明的函數(shù)f和變量c,先被詞法預(yù)解析。

第2步,在JavaScript執(zhí)行期,調(diào)用函數(shù)f,并傳入值5。

第3步,在解析函數(shù)f時(shí),將創(chuàng)建執(zhí)行環(huán)境(函數(shù)作用域),創(chuàng)建活動(dòng)對(duì)象,把參數(shù)和私有變量、內(nèi)部函數(shù)都映射為活動(dòng)對(duì)象的屬性。

第4步,參數(shù)x的值為5,映射到活動(dòng)對(duì)象的x屬性。

第5步,內(nèi)部函數(shù),通過(guò)作用域鏈,引用了參數(shù)x,但是還沒(méi)有被執(zhí)行。

第6步,外部函數(shù)被調(diào)用后,返回內(nèi)部函數(shù),導(dǎo)致內(nèi)部函數(shù)被外界變量c引用。

第7步,JavaScript解析器檢測(cè)到外部函數(shù)活動(dòng)對(duì)象的屬性被外界引用,無(wú)法注銷該活動(dòng)對(duì)象,于是在內(nèi)存中繼續(xù)維持該對(duì)象的存在。

第8步,當(dāng)調(diào)用c,即調(diào)用內(nèi)部函數(shù)時(shí),可以看到外部函數(shù)的參數(shù)x存儲(chǔ)的值繼續(xù)存在,于是也就可以實(shí)現(xiàn)后續(xù)運(yùn)算操作,返回x+y=5+6=ll。

■小結(jié)

下面的結(jié)構(gòu)形式也可以形成閉包:通過(guò)全局變S引用內(nèi)部函數(shù),實(shí)現(xiàn)內(nèi)部函數(shù)對(duì)外開放。

var c;                        //聲明全局變量

function f(x){                //外部函數(shù)

    c = function(y){          //內(nèi)部函數(shù),通過(guò)向全局變量開放實(shí)現(xiàn)外部引用

        return x + y;         //訪問(wèn)外部函數(shù)的參數(shù)

    };

}

f (5);                        //調(diào)用外部函數(shù)

console.log(c(6));            //使用全局變量c調(diào)用內(nèi)部函數(shù),返回11

繼續(xù)查找其他問(wèn)題的答案?

相關(guān)視頻回答
回復(fù)(0)
返回頂部