先上版圖

//3月3號老任就要發(fā)售Switch了,還有塞爾達(dá)護(hù)航新作好激動呀,然而我并沒有錢買...
1、JS閉包
閉包在程序界是一個很抽象的概念,以至于被人稱為編程界的哈姆雷特,我們先來看看MDN對其的解釋
Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.
- 閉包是一個函數(shù),特指那些可以訪問獨立變量的函數(shù)(這種獨立變量在本地使用,但是卻定義在一個封閉的作用域),換句話說這類函數(shù)能夠記憶創(chuàng)建它們時的環(huán)境
其實我個人理解更傾向于:
當(dāng)嵌套函數(shù)的引用傳遞給了嵌套函數(shù)作用域之外的變量,或者對象的屬性,此時就會形成一個閉包
嗯,解釋的很好,但我還是不知道這是個啥
那還是少廢話上代碼吧。。
function person() {
var name = 'ergouzi';
console.log(name);
}
person();
console.log(name);
輸出:
//ergouzi
//undefined
很普通的一個函數(shù),正常理解函數(shù)與變量的思維就是:函數(shù)執(zhí)行,定義變量,函數(shù)執(zhí)行完畢,變量銷毀。再來看看另一種寫法
function person() {
var name = 'ergouzi';
var nameFunc = function() {
console.log(name);
}
return nameFunc;
}
var personFunc = person();
personFunc();
輸出:
//ergouzi
可以看到,這里即使person函數(shù)執(zhí)行完畢了,但是里面的name變量卻沒有被銷毀,這里再套用開頭解釋的概念,應(yīng)該能理解部分了吧。咱們再來驗證一下這種“被記憶的獨立變量”的特性
function person() {
var name = 'ergouzi';
var funcObj = {
'nameFunc': function () {
console.log(name);
},
'changeFunc': function () {
name = 'goudanzi';
}
}
return funcObj;
}
var funcObj = person();
funcObj.changeFunc();
funcObj.nameFunc();
輸出:
//goudanzi
可以看到,我們在該獨立變量的作用域外部改變了它的值,所以說明相同環(huán)境里創(chuàng)建的閉包函數(shù),引用的獨立變量為同一份拷貝,即同一個對象。其實用chrome調(diào)試一下就能很清楚的看到閉包函數(shù)長啥樣,比如我這里的閉包函數(shù)它長這樣(還長得挺漂亮的)

我們可以看到兩個函數(shù)“changeFunc”,“nameFunc”,從他們的Scopes里面都能找到Closure并且創(chuàng)建環(huán)境都為person,記憶的獨立變量都為“name”,
再來看點哦莫西羅伊的
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i)
}, 0);
}
輸出:
//10
//10
//10
//10
//10
//10
//10
//10
//10
//10
//簡要解釋一下輸出值,因為setTimeout是異步函數(shù),在i=0第一次循環(huán)時只是定義了第一個定時函數(shù)而并沒有執(zhí)行它,待到執(zhí)行第一個定時函數(shù),但此時i的值已經(jīng)變了
一個普通的for循環(huán),每次循環(huán)定義了一個定時器函數(shù),因為沒有給定時器函數(shù)的句柄傳參,它只能拿到i最后的值。我們換一種“閉包”一點的寫法
for (var i = 0; i < 10; i++) {
setTimeout(((j) => console.log(j))(i), 0);
}
//或者這樣寫
for (var i = 0; i < 10; i++) {
(j => setTimeout((j) => console.log(j), 0))(i);
}
這里用到了es6的箭頭函數(shù),想詳細(xì)了解箭頭函數(shù)請移步箭頭函數(shù)
這里的代碼將每次循環(huán)的i值傳給了一個閉包函數(shù),此時這個閉包函數(shù)記憶了這個i的值,等到執(zhí)行定時函數(shù)時,就可以正常打印出i值。
參考文檔https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
//未完待續(xù),懶癌犯了剩下的下次補(bǔ)...
//接下來是每周最開心的游戲時間,仁王繼續(xù)落命中...