學習js,閉包一直是反覆討論的問題,這裏,我就根據自己的所見及理解,討論與閉包有關的東西
function f(){
var a=2;
function m(){
console.log(a)
}
m();
}
f();
js中經常出現這樣的情況,有些變量我們既希望用到它又不想讓它污染全局環境,所以我們在外部又加了一層函數,這樣函數m()調用了外部函數f()的變量a,嚴格來說,這就是運用閉包了。再來看下面的程序:
function f(){
var a=2;
return function() {
console.log(a)
}
}
var m=f();
m();
到這裏,便出現了我們最順眼的閉包形式,內部函數脫離外部函數,可以直接在全局調用函數內部的函數,這裏也符合維基百科等定義機構對閉包的定義。
那閉包這種特殊的形式有什麼妙用呢,接下來繼續看
function f(){
var a=2;
return function() {
a++;
console.log(a);
}
}
var m=f();
m();
m();
m();
以上這段程序我們做的是重複調用函數實現變量累加,試想我們直接調用函數f()的話,結果三次都會重複輸出3,因爲每次調用都在重新定義變量,這樣我們只能把變量放在全局環境中才能實現,那麼就會污染全局環境,所以閉包的價值體現出來了。接下來再看
function f(base){
return function(max){
var total=0;
for(var i=0;i<=max;i++){
total+=i;
}
return total+base;
}
}
var adder=f(2);
alert(adder(3));//3+2+1+2=8
這段代碼實現的是從0到max累加後再與基數base相加,最後返回結果,這裏我們用到了兩個參數——base,max。然而我們是用一個參數來實現的,另一個參數隱藏在了內部函數中,這也是閉包給我們帶來的便捷。再看:
(function(){
var m=0;
function getM(){
return m;
}
function setM(val){
m=val;
}
window.g=getM;
window.s=setM;
})()
s(12);
alert(g());
這裏用到一點面向思想的編程模式,不過也是對閉包的完美應用,變量m定義在函數中,getM()和setM()函數也調用了父函數的變量,是典型的閉包結構。