一、 閉包的定義
能通路其他函數内變量的函數,這種結構就是閉包
二、閉包的用途
1.讀取函數内部的變量
2.讓這些變量的值始終保持在記憶體中(結果緩存)
3.建立匿名自執行函數(避免全局變量的污染)
三、閉包的弊端
1.使用不當會很容易造成記憶體洩露
2.常駐記憶體,增加記憶體使用量
四、實際應用
接下來舉一些實際工作中用到的閉包示例
1.自定義Alert彈框,該彈框隻會被new一次,用的就是閉包
module.alert = (function(){
var box;
return function(text){
box = box || new Alert();
box.append('body', text);
return box.show();
}
})();
2.私有化變量
var counter = (function(){
//私有變量
var privateCounter = 0;
return {
increment:function(){
privateCounter++;
},
decrement:function(){
privateCounter--;
},
getValue:function(){
return privateCounter;
}
};
})();
console.log(counter.getValue()); //0
counter.increment();
console.log(counter.getValue()); //1
counter.decrement();
console.log(counter.getValue()); //0
3.利用閉包判斷類型
const isType = type => target => `[object ${type}]` === Object.prototype.toString.call(target);
const isArray = isType('Array');
console.log(isArray([])); //true
console.log(isArray({})); //false
4.斐波那契數列求和
//n為數列項數,從1開始
//如 1 1 2 3 5 8 13 21 該斐波那契數列的n為8
let fibonacci = function(n){
if(n < 1) throw new Error('參數有誤');
if(n === 1 || n === 2) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
//定義一個閉包函數,将每次求和的結果記錄在obj上
const memory = function(fn){
const obj = {};
return function(n){
//如果obj上沒有n項數列的結果,就調用上面定義的方法計算,然後将結果儲存在obj上;
if(obj[n] === undefined) obj[n] = fn(n);
return obj[n];
}
}
//此處重新用閉包後傳回的方法替換上面定義的fibonacci方法,可以将n及之前每一項的結果都緩存在obj上,第一次計算會多耗一些時間,但是下次計算如果n之前已經計算過,便可以直接取結果
fibonacci = memory(fibonacci);
fibonacci(6) //8
fibonacci(8) //21
fibonacci(10) //55