閉包的概念
閉包 : 如果一個「函數」使用了它范圍外的「變量」涛贯,那么這個「函數」加上這個「變量」就是一個閉包湘今。
最簡單的閉包模型
var n;
function x(){
console.log(n)
}
有 return 和 函數包裹的閉包模型
function x(){
var n= 666;
function y(){
console.log(n)
}
return y
}
var z = x();
z() //666
上面代碼里的 y 函數與 n 變量就構成了一個閉包。
為什么要函數套函數呢择葡?
是因為需要局部變量,所以才把 n 放在一個函數里,如果不把 n 放在一個函數里辛臊,n 就是一個全局變量了,達不到使用閉包的目的——隱藏變量房交。
函數套函數只是為了造出一個局部變量彻舰,跟閉包無關。
為什么要 return y 呢?
因為如果不 return刃唤,你就無法使用這個閉包隔心。
return是要讓外面可以訪問到這個 y 函數就行了。
所以 return y 只是為了 y 能被使用尚胞,也跟閉包無關硬霍。
閉包的作用
1.讀取函數內部的變量
function f1() {
var n = 999;
function f2() {
console.log(n);
}
return f2;
}
var result = f1();
result(); // 999
上面代碼中,函數 f1 的返回值就是函數 f2 笼裳,由于 f2 可以讀取 f1 的內部變量唯卖,所以就可以在外部獲得 f1 的內部變量了。
2.讓這些變量始終保持在內存中躬柬,即閉包可以使它誕生環(huán)境一直存在
function xxx(start) {
return function () {
return start++;
};
}
var inc = xxx(5);
inc() // 5
inc() // 6
inc() // 7
上面代碼中拜轨,start 是函數 xxx 函數的內部變量。通過閉包楔脯,start的狀態(tài)被保留了撩轰,每一次調用都是在上一次調用的基礎上進行計算。從中可以看到昧廷,閉包inc使得函數 xxx 的內部環(huán)境堪嫂,一直存在。所以木柬,閉包可以看作是函數內部作用域的一個接口皆串。
為什么會這樣呢?
原因就在于 inc 始終在內存中眉枕,而 inc 的存在依賴于 xxx 函數恶复,因此也始終在內存中,不會在調用結束后速挑,被垃圾回收機制回收谤牡。
參考:方應杭:閉包