《JavaScript高級程序設計》:緩存
閉包是指有權訪問另外一個函數做用域中的變量的函數;bash
《JavaScript權威指南》:閉包
從技術的角度講,全部的JavaScript函數都是閉包:它們都是對象,它們都關聯到做用域鏈。app
《你不知道的JavaScript》:√函數
當函數能夠記住並訪問所在的詞法做用域時,就產生了閉包,即便函數是在當前詞法做用域以外執行。ui
當內部函數被保存到外部時,將會生成閉包。閉包會致使原有做用域鏈不釋放,形成內存泄露. 閉包的本質就是函數嵌套,內部函數能夠引用外部函數的參數和變量,參數和變量不會被回收機制回收。spa
內部的函數被返回到外部,必然造成閉包設計
function a(){
function b(){
var b = 234;
console.log(a);
}
var a = 123;
return b;
}
var demo = a();
demo(); // -->123
複製代碼
function test1(){
var num = 100;
function test2(){
num ++;
console.log(num);
}
return test2;
}
var demo1 = test1();
demo1(); //101
demo1(); //102
//
function test(){
var arr = [];
for(var i = 0; i < 10; i++){//當i = 10的時候循環中止
arr[i] = function(){ //arr的每一位都是一個函數
console.log(i);//雖然函數已經定義,但未執行
}
}
return arr;
}
var myArr = test();
for(var i = 0; i < myArr.length; i++ ){
myArr[i]();
}
複製代碼
最後函數執行的時候會調用test的AO中的icode
AO{對象
i = 10;
}
解決方案:當即執行函數
function test() {
var arr = [];
for(var i = 0; i < 10; i++) {
(function(j) {
arr[j] = function() {
console.log(j);} }(i))
}
return arr;
}
var myArr = test();
for(var i = 0; i < myArr.length; i++) {
myArr[i]();
}
複製代碼
eg:函數累加器
function add(){
var count = 0;
function demo(){
count ++ ;
console.log(count);
}
return demo;
}
var counter = add();
counter();
複製代碼
eg:eater
function test2(){
var food = 'apple';
var obj = {
eatFood : function(){
if(food != ""){
console.log("I am eatting " + food);
food = '';
}else{
console.log("There is nothing! empty!");
}
},
pushFood : function(myFood){
food = myFood;
}
}
return obj;
}
var obj = test2();
obj.eatFood();
obj.eatFood();
obj.pushFood('banana');
obj.eatFood();
複製代碼
eg: Person();