If you can't explain it to a six-year-old, you really don't understand it yourself.
閉包(closure)是JavaScript語言的一個難點,也是JavaScript的一個特色,很多高級的應用都要依靠閉包來實現。
作用域
在js中,函數會形成函數作用域,在函數內部可以直接訪問全局變量
varstr="zs";
functionfn(){
console.log(str);//訪問全局變量
}
fn();//zs
在函數外部卻無法訪問函數內部的變量
functionfn(){
varstr="zs";
}
fn();
console.log(str);//報錯 str is not defined
問題:我怎么才能獲取到函數內部的變量?
作用域鏈
在函數內部有一個函數,那么函數內部的函數是可以訪問到外部函數的變量的。
解決方法:
functionfn(){
varstr="zs";
functionf2(){
console.log(str);
}
f2();
}
fn();
在上述代碼中,fn中定義的所有變量,對于f2函數都來都是可以訪問的。但是現在f2在函數的內部,我們如何在外部訪問到f2這個函數呢?
functionfn(){
varstr="zs";
functionf2(){
console.log(str);
}
returnf2;
}
varresult=fn();
result();// "zs"
閉包的概念
上面代碼中的f2就是閉包,閉包就是能夠讀取到其他函數內部變量的函數。因此我們可以把閉包理解為定義在函數內部的函數;
閉包是函數內部與外部連接起來的橋梁。
閉包的應用
計數器
需求:統計一個函數的調用次數
varcount=0;
functionfn(){
count++;
console.log("我被調用了,調用次數是"+count);
}
fn();
fn();
fn();
缺點:count是全局變量,不安全。
使用閉包解決這個問題!!!!
functionouter(){
varcount=0;
functionadd(){
count++;
console.log("當前count"+count);
}
returnadd;
}
varresult=outer();
result();
私有變量
使用閉包實現私有變量的讀取和設置
functionouter(){
varnum=10;
functionset_num(n){
num=n;
}
functionget_num(){
returnnum;
}
return{
set_num:set_num,
get_num:get_num
}
}
varobj=outer();
obj.set_num(2000);
console.log(obj.get_num());