* 定義:一個函數可以訪問另一個函數內部的變量
* 形成條件
1. 一個函數(fn1)的返回值是另一個函數(fn2)
2. fn2中調用了fn1內部的變量
3. fn2在外部執行了
*
* 作用
1. 實現封裝過程。封裝對象中的變量不能直接訪問,提過返回的getter/setter方法來訪問。
```
function Person() {
var name = '張三';
return {
getName() {
return this.name;
},
setName(value) {
this.name = value;
}
}
}
```
2. 模擬塊級作用域
```
function fn(num){
for(var i=0; i<num; i++){}
console.log(i);
}
fn(2); //2
// 通過閉包模擬實現
function fn(num){
(function(){
for(var i=0; i<num; i++){}
})();
console.log(i);
}
fn(2); //error "i is not defined"
```
3. 解決for循環的問題
```
function fn(){
for(var i=0; i<5; i++){
setTimeout(function(){
console.log(i);
},i*1000);
}
}
fn(); //每隔1s輸出一次"5",共輸出4次
//原因:i是var聲明的變量,在函數范圍內有效,每次for循環全局變量的i都會改變,所有每次輸出的都是同一個i
// 通過閉包解決
function fn(){
for(var i=0; i<5; i++){
(function(j){
setTimeout(function(){
console.log(j);
},i*1000);
})(i);
}
}
fn(); //每隔1秒分別輸出0 1 2 3 4
```