日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

自由變量與閉包

 昵稱10087950 2022-06-16 發(fā)布于江蘇

在講閉包之前,我們先了解一下什么是自由變量。

自由變量是指在函數(shù)中使用的,但既不是函數(shù)參數(shù)也不是函數(shù)的局部變量的變量

示例代碼:

let a = 1;

function foo() {
console.log(a);
}

foo();

上述代碼中,對(duì)于函數(shù) foo 來(lái)說(shuō),a 既不是函數(shù)參數(shù)也不是函數(shù)的局部變量的變量,因此 a 屬于自由變量。

什么是閉包

在ECMAScript中,閉包(Closure)是指能夠訪問(wèn)自由變量的函數(shù)。

按照以上的概念,我們可以說(shuō)所有函數(shù)都是閉包,因?yàn)樗鼈兌际窃趧?chuàng)建的時(shí)候就保存了上層上下文的作用域鏈,觀察如下代碼:

let a = 1;

function foo() {
console.log(a);
}

foo(); // > 1

(function () {

let a = 2;
foo(); // > 1

})();

ECMAScript 使用的是詞法作用域(Lexical scoping,又稱靜態(tài)作用域),即在函數(shù)創(chuàng)建時(shí),就保存上層上下文的作用域鏈,上述代碼中,foo 函數(shù)創(chuàng)建時(shí),其所使用的變量 a 是已經(jīng)在上下文中靜態(tài)保存好的,因此在執(zhí)行 foo() 時(shí) a 的值為 1。

而任何函數(shù),在其創(chuàng)建時(shí)保存的上層上下文的作用域中都有全局的自由變量 global(在瀏覽器中,global 為 window),因此說(shuō)所有函數(shù)都是閉包。

實(shí)踐中的閉包

上面說(shuō)的是理論上的閉包,但在實(shí)踐中,閉包不僅僅只是能夠訪問(wèn)自由變量的函數(shù),閉包是指引用了自由變量的,并且被引用的自由變量將和這個(gè)函數(shù)一同存在的函數(shù),在創(chuàng)建該函數(shù)的上下文已經(jīng)銷毀時(shí),該函數(shù)仍然存在。

示例代碼:

function foo(){
let a = 1;

return function(){
console.log(a)
}
}
foo()

上述代碼中,foo 函數(shù)執(zhí)行后返回了一個(gè)匿名函數(shù),該函數(shù)引用了自由變量 a,而在 foo() 執(zhí)行完畢后,創(chuàng)建該函數(shù)的環(huán)境已經(jīng)銷毀,但該函數(shù)并沒(méi)有被銷毀,因此 foo() 的返回值就是一個(gè)閉包。

閉包會(huì)使引用的自由變量不能被清除,這就使得閉包比其他函數(shù)占用內(nèi)存更多,但這也是閉包的強(qiáng)大之處,以下是一個(gè)使用閉包的例子:

let foo = function() {

let a = 1;

return {
add:function(){
return ++a;
},
sub:function(){
return --a;
}
}
}

let f = foo();
f.add(); // 2
f.sub(); // 1

再來(lái)看一個(gè)面試中經(jīng)常遇到的題目:

let data = [];

for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}

data[0](); // 3
data[1](); // 3
data[2](); // 3

這三個(gè)函數(shù)創(chuàng)建時(shí)均使用的是已經(jīng)在上下文中靜態(tài)保存好的變量 i,而在 for 循環(huán)結(jié)束時(shí),變量i 的值為3,當(dāng) data[0]() 執(zhí)行時(shí),其所引用的自由變量 i 的值為 3,因此輸出3。

我們的目標(biāo)是輸出0、1、2,上面的例子顯然無(wú)法實(shí)現(xiàn)這個(gè)需求,利用閉包可以很輕松地解決這個(gè)問(wèn)題:

let data = [];

for (var i = 0; i < 3; i++) {
data[i] = (function(x) {
return function () {
alert(i);
};
})(i); // 傳入"i"值
}

data[0](); // 0
data[1](); // 1
data[2](); // 2

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多