1.什么是閉包
要理解什么是閉包,就得先理解變量的作用域掏颊。
在JavaScript中,有兩種作用域,全局作用域和函數(shù)作用域乌叶。
var a=1;
function fn(){
var b =2;
console.log(a)
}
fn.call() // 3
console.log(b) //Uncaught ReferenceError: n is not defined
上面代碼中盆偿,函數(shù)fn可以讀取全局變量a,但是函數(shù)外部無法讀取函數(shù)內(nèi)部聲明的變量b准浴。這就是全局作用域和函數(shù)作用域事扭。
function fn1(){
var a =1;
function fn2(){
console.log(a)
}
return fn2;
}
閉包的官方解釋為,閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合乐横。
說的比較生僻難懂求橄。通俗些說就是,如果一個函數(shù)使用了函數(shù)作用域范圍外的變量葡公,那么這個函數(shù)和這變量就可以稱為一個閉包罐农。
上面例子中,函數(shù)fn2和變量a就可以稱為一個閉包催什。
2.閉包的用途
閉包的用途主要三個涵亏,讀取函數(shù)內(nèi)部的變量、讓變量始終保留在內(nèi)存中蒲凶、封裝對象的私有屬性和私有方法气筋。
2.1.讀取函數(shù)內(nèi)部變量
function fn1(){
var a =1;
function fn2(){
console.log(a)
}
return fn2;
}
var number =fn1(); // 輸出為1,即可獲取到函數(shù)fn1內(nèi)的變量a旋圆。
上述代碼中宠默,函數(shù)fn1返回值為fn2,fn2可以獲取到fn1的函數(shù)內(nèi)變量灵巧,所以就可以函數(shù)f1的內(nèi)部變量了光稼。
2.2.讓變量始終保留在內(nèi)存中
function fn(x){
return function(){
return x++;
}
}
var number= fn(1);
number.call(); //1
number.call(); //2
number.call(); //3a
2.3.封裝對象的私有屬性和私有方法
function fn(x){
return function(){
return x++
}
}
var a =fn(1);
a(); //1
a(); //2
var b =fn(5);
b(); //5
b(); //6
var c =fn(10);
c(); //10
c(); //11
上述代碼中,外層函數(shù)fn每次運行孩等,都會生成一個新的閉包艾君,而這個閉包又會保留外層函數(shù)的內(nèi)部變量。
a肄方、b冰垄、c 是相互獨立的,函數(shù)fn的內(nèi)部變量參數(shù)x权她,通過閉包虹茶,變成了a、b隅要、c各自的私有變量參數(shù)蝴罪。
3.閉包的缺點
閉包會使函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存占據(jù)很大步清,使用閉包時應(yīng)格外注意內(nèi)存消耗大要门,否則會造成網(wǎng)頁的性能問題虏肾。