閉包
所有的函數(shù)式編程語言中,閉包的概念都尤為重要垂蜗。Javascript 作為 github 上第一語言,是當(dāng)今 “最好的語言” 解幽。如果你對這個還存有異議贴见,我猜你八成不懂 JS 的閉包。
廢話不多說躲株,進(jìn)入正題片部,先上個代碼
var i = 0;
function generator(){
return function(){
i++;
return i;
}
}
var f1 = generator();
console.log(f1()); // #1: 1
console.log(f1()); // #2: 2
對于上面的例子霜定,函數(shù) f1 是由 generator 函數(shù)生成的档悠。很明顯,它們的運(yùn)行結(jié)果是和 generator 外的變量 i 相關(guān)望浩,我們稱這類的函數(shù)為”非封閉"的辖所。
我們再看下面這個例子
function f(){
var i = 0;
i++;
return i;
}
從上面的代碼可以看出,函數(shù) f 的運(yùn)行不依賴任何外界因素磨德,我稱它是“封閉”的缘回。
封閉與非封閉
對于“封閉”函數(shù),你不管在何處剖张、在何時調(diào)用它切诀,它的執(zhí)行結(jié)果總是一致的,比如上面的 f() 永遠(yuǎn)返回 1.
對于“非封閉”函數(shù)搔弄,調(diào)用它的話幅虑,它的執(zhí)行結(jié)果是和調(diào)用時機(jī)有關(guān)的,因?yàn)樗膱?zhí)行和它外面的環(huán)境有關(guān)顾犹。在上面的例子中倒庵, f1 的執(zhí)行結(jié)果,與全局變量 i 相關(guān)炫刷。比如
var i = 0擎宝;
function generator(){
return function(){
i++;
return i;
}
}
var f1 = generator();
f1() // 1
i = 10
f1() // 11
因?yàn)?f1 依賴變量 i,所以只要 i 的值發(fā)生變化浑玛,f1 的行為就會受到影響绍申。或者說,f1 的行為不被 f1 自己完全控制极阅。忽視變量 i胃碾,你就不能對 f1 的執(zhí)行結(jié)果進(jìn)行有效預(yù)測。
另一方面筋搏,只要 f1 所依賴的所有外界因素都保持不變(這里指變量 i)仆百,那么 f1 的行為就可以被預(yù)測。
換句話說奔脐, f1 + “所依賴的外界因素” = 一個“封閉”的系統(tǒng)俄周,我們把這個系統(tǒng)稱為一個“閉包”。
后續(xù)話題
本片文章簡單地介紹了閉包的概念髓迎,如果要更好地理解峦朗、掌握閉包,下面這些領(lǐng)域必須要搞清楚
- 變量的生命周期
- 作用域
- 變量垃圾回收機(jī)制(GC)
比如下面這個例子
function generator(){
var i = 0;
return function(){
i++;
return i;
}
}
var f1 = generator(),
f2 = generator();
console.log(f1()); // 1
console.log(f1()); // 2
console.log(f2()); // 1
console.log(f2()); // 2
以及
function test(a){
a = {
name: "changed"
};
}
var b = {
name: "hello"
}
test(b);
console.log(b.name); // hello
文章的鏈接后續(xù)加上竖般。甚垦。。