真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

javascript中的閉包-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)javascript中的閉包,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

浦北網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、自適應(yīng)網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)公司從2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。

閉包并不是 JavaScript 特有的,大部分高級(jí)語(yǔ)言都具有這一能力。

什么是閉包?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment).

這段是 MDN 上對(duì)閉包的定義,理解為:一個(gè)函數(shù)及其周圍封閉詞法環(huán)境中的引用構(gòu)成閉包。可能這句話還是不好理解,看看示例:

function createAction() {
    var message = "封閉環(huán)境內(nèi)的變量";
    
    return function() {
        console.log(message);
    }
}

const showMessage = createAction();
showMessage();    // output: 封閉環(huán)境內(nèi)的變量

這個(gè)示例是一個(gè)典型的閉包,有這么幾點(diǎn)需要注意:

  1. showMessagecreateAction 執(zhí)行后從中返回出來(lái)的一個(gè)函數(shù)。
  2. createAction 內(nèi)部是一個(gè)封閉的詞法環(huán)境,message 作為該封裝環(huán)境內(nèi)的變量,在外面是絕不可能直接訪問(wèn)。
  3. showMessagecreateAction 外部執(zhí)行,但執(zhí)行時(shí)卻訪問(wèn)到其內(nèi)部定義的局部變量 message(成功輸出)。這是因?yàn)?showMessage 引用的函數(shù)(createAction 內(nèi)部的匿名函數(shù)),在定義時(shí),綁定了其所處詞法環(huán)境(createAction 內(nèi)部)中的引用(message 等)。
  4. 綁定了內(nèi)部語(yǔ)法環(huán)境的匿名函數(shù)被 return 帶到了 createAction 封閉環(huán)境之外使用,這才能形成閉包。如果是在 createAction 內(nèi)部調(diào)用,不算是閉包。

好了,我相信 1, 2, 4 都好理解,但是要理解最重要的第 3 點(diǎn)可能有點(diǎn)困難 —— 困難之處在于,這不是程序員能決定的,而是由語(yǔ)言特性決定的。所以不要認(rèn)為是“你”創(chuàng)建了閉包,因?yàn)殚]包是語(yǔ)言特性,你只是利用了這一特性。

如果語(yǔ)言不支持閉包,類似上面的代碼,在執(zhí)行 showMessage 時(shí),就會(huì)找不到 message 變量。我特別想去找一個(gè)例子,但是很不幸,我所知道的高級(jí)語(yǔ)言,只要能在函數(shù)/方法內(nèi)定義函數(shù)的,似乎都支持閉包。

把局部定義的函數(shù)“帶”出去

前面我們提到了可以通過(guò) return 把局部定義的函數(shù)帶出去,除此之外有沒(méi)有別的辦法?

函數(shù)在這里已經(jīng)成為“貨”,和其他貨(變量)沒(méi)有區(qū)別。只要有辦法把變量帶出去,那就有辦法把函數(shù)帶出去。比如,使用一個(gè)“容器”對(duì)象:

function encase(aCase) {
    const dog = "狗狗";
    const cat = "貓貓";
    aCase.show = function () {
        console.log(dog, cat);
    };
}

const myCase = {};
encase(myCase);
myCase.show();      // output: 貓貓 狗狗

是不是受到了啟發(fā),有沒(méi)有聯(lián)想到什么?

模塊和閉包

對(duì)了,就是 exports 和 module.exports。在 CJS (CommonJS) 定義的模塊中,就可以通過(guò) exports.something 逐一帶貨,也可以通過(guò) module.exports = ... 打包帶貨,但不管怎么樣,exports 就是帶貨的那一個(gè),只是它有可能是原來(lái)安排的 exports 也可能是被換成了自己人的 exports。

ESM (ECMAScript Module) 中使用了 importexport 語(yǔ)法,也只不過(guò)是換種方法帶貨出去而已,和 return 帶貨差不多,區(qū)別只在于 return 只能帶一個(gè)(除非打包),export 可以帶一堆。

還要補(bǔ)充的是,不管是 CJS 還是 ESM,模塊都是一個(gè)封裝環(huán)境,其中定義的東西只要不帶出去,外面是訪問(wèn)不到的。這和網(wǎng)頁(yè)腳本默認(rèn)的全局環(huán)境不同,要注意區(qū)別。

如果用代碼來(lái)表示,大概是定義模塊的時(shí)候以為是這樣:

const var1 = "我是一個(gè)頂層變量吧";
function maybeATopFunction() { }

結(jié)果在運(yùn)行環(huán)境中,它其實(shí)是這樣的(注意:僅示意):

// module factory
function createModule_18abk2(exports, module) {
    const var1 = "我是一個(gè)頂層變量吧";
    function maybeATopFunction() { }
}

// ... 遙遠(yuǎn)的生產(chǎn)線上,有這樣的示意代碼
const module = { exports: {} };
const m18abk2 = createModule_18abk2(module) ?? module;

// 想明白 createModule_18abk2 為什么會(huì)有一個(gè)隨機(jī)后綴沒(méi)?

還是那個(gè)函數(shù)嗎?

扯遠(yuǎn)了,拉回來(lái)。思考一個(gè)問(wèn)題:理論上來(lái)說(shuō),函數(shù)是一個(gè)靜態(tài)代碼塊,那么多次調(diào)用外層函數(shù)返回出來(lái)的閉包函數(shù),是同一個(gè)嗎?

試試:

function create() {
    function closure() { }
    return closure;
}

const a = create();
const b = create();

console.log(a === b);   // false

如果覺(jué)得意外,那把 closure() 換種方式定義看會(huì)不會(huì)好理解一點(diǎn):

function create() {
    closure = function() { }
    return closure;
}

如果還不能理解,再看這個(gè):

function create() {
    const a = function () { };
    const b = function () { };
    console.log(a === b);   // false
}

閉包是由一個(gè)函數(shù)以及其定義時(shí)所在封閉環(huán)境內(nèi)的各種資源(引用)構(gòu)成,拿到的每一個(gè)閉包都是獨(dú)一無(wú)二的,因?yàn)闃?gòu)成閉包的環(huán)境資源不同(不同的局部環(huán)境,定義了不同的局部變量,傳入了不同的參數(shù)等)。

關(guān)于javascript中的閉包就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


本文標(biāo)題:javascript中的閉包-創(chuàng)新互聯(lián)
文章鏈接:http://weahome.cn/article/decgjg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部