js中的閉包

閉包,英文叫做closure,借用MDN中的解釋,一個函數(shù)和對其周圍狀態(tài)(lexical environment,詞法環(huán)境)的引用捆綁在一起(或者說函數(shù)被引用包圍),這樣的組合就是閉包(closure)。js中的閉包有以下幾個特性:

? ? 1.存在函數(shù)的嵌套

? ? 2.內(nèi)部函數(shù)可以引用外部的變量以及參數(shù)

? ? 3.變量以及參數(shù) 不會被垃圾回收機制回收

例子如下:

function?outFn(){

???var?name?=?'wolfBite'; // 外部函數(shù)變量

???function?innerFn(){ //內(nèi)部函數(shù)

??????console.log( 'hi '+name +'!') //引用外部的變量 name

???}

???innerFn();

}

outFn(); // hi?wolfBite!

????函數(shù)outFn定義了局部變量 name 和函數(shù) innerFn,函數(shù)innerFn中的console語句 引用name,注意函數(shù)innerFn內(nèi)部沒有定義局部變量name,? ?最后函數(shù)outFn執(zhí)行了函數(shù)innerFn。調(diào)用ouFn(),打印出問候語‘hi wolfBite!’。

第二個例子如下:

function?outFn(){

???var?name?=?'wolfBite';?//?外部函數(shù)變量

???function?innerFn(){?//內(nèi)部函數(shù)

??????console.log(?'hi?'+name?+'!')?//引用外部的變量?name

???}

???return?innerFn; //直接返回

}

var?myFn?=?outFn(); // 接收返回值(此時outFn執(zhí)行完了,但變量name并沒有被回收機制回收)

myFn();// hi?wolfBite!

????會發(fā)現(xiàn)例子二和例子一的區(qū)別,函數(shù)outFn最后沒有直接執(zhí)行innerFn,而是將函數(shù)innerFn返回,代碼最后沒有直接執(zhí)行函數(shù)outFn,而是將outFn的執(zhí)行結果(函數(shù)innerFn)返回給變量myFn ,最后再執(zhí)行myFn();

????你可能會覺得執(zhí)行完 ‘var?myFn?=?outFn();’這語句之后,outFn內(nèi)部定義的變量name已經(jīng)被回收機制回收了,innerFn無法訪問這個變量,然而代碼仍按預期運行。原因是函數(shù)innerFn形成了閉包,這個閉包是由這個函數(shù)和創(chuàng)建該函數(shù)時的詞法環(huán)境組合而成,這個環(huán)境包含了這個閉包創(chuàng)建時所有的局部變量。例子二中myFn 是 執(zhí)行outFn時返回的innerFn實例的引用,innerFn的實例維持了一個對它的詞法環(huán)境(變量?name?存在于其中)的引用,因此當myFn調(diào)用時,變量name仍可訪問。

閉包 - JavaScript | MDN

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容