版權聲明:本文為部落客原創文章,轉載請注明出處。 https://blog.csdn.net/twilight_karl/article/details/60592592
閉包
1,閉包可以讓局部變量駐留在記憶體中,而不會重複初始化
2,過度使用會導緻記憶體占用過高,是以用完後應及時解除引用:
b = null
function add(){
var num = 100;
return function(){
return num++;
};
};
var fun3 = add(); // 獲得閉包函數,add函數隻初始化一次
alert(fun3()); // 101
alert(fun3()); // 102
alert(fun3()); // 103
alert(fun3()); // 104
fun3 = null; // 過多的使用閉包會占用大量記憶體,使用完後要釋放閉包函數:
alert(fun3()); // 報錯
以循環裡的匿名函數的取值為例,分三種情況:
<1>: 傳回的閉包函數由于是在sum執行完後再執行,是以傳回的值都是5.數組中儲存的是匿名函數,需要用函數的方式調用。
// 001
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = function(){
return i;
}
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 全部是5
alert(data[i]());
}
<2>: 利用函數的自我執行即時的給數組指派,傳回的數組内容是數字
// 002
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = (function(num){ // 匿名函數的即時執行
return num;
})(i);
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 正常
alert(data[i]);
}
<3>: 使用函數的自我執行的同時傳回一個匿名函數,傳回的數組需要當成函數調用
// 003
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = function(num){ // 匿名函數的即時執行
return function(){
return num;
};
}(i);
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 正常
alert(data[i]());
}
閉包中的this
閉包中的this指向window,閉包并不屬于某個對象的屬性和方法。解決方法:對象冒充。
var flag = "window";
var box = {
flag : "box",
fun : function(){
return function(){
return this.flag;
}
}
};
alert(box.fun()()); // 閉包的this指向window
可以使用以下的方法解決,不直接使用閉包中的this,而是儲存普通函數中的this,再在閉包中調用:
var box2 = {
flag : "box",
fun : function(){
var sss = this;
return function(){
return sss.flag;
}
}
};
alert(box2.fun()()); // box2
使用call或者apply更改作用域也可以解決問題:
var box3 = {
flag : "box",
fun : function(){
return function(){
return this.flag;
}
}
};
alert(box3.fun().call(box3));
私有作用域
JavaScript沒有塊級作用域,但是自我執行的匿名函數有私有作用域,作用域中的變量在執行完後就被銷毀,在作用域外無法被調用。可以減少全局變量的使用。
(function(){
for(var i=0;i<5;i++){}
})();
alert(i); // undefined
私有變量
this.屬性或this.方法表示的是共有方法和屬性。但是在方法中用var聲明的方法或屬性是私有屬性,外部無法調用,用該函數建立的對象也無法使用私有屬性。
function Person(str){
var name = str; // 私有屬性
var fun = function(){ // 私有方法
return name+"###";
};
};
var tom = new Person("Tom");
alert(tom.fun()); // 報錯
alert(tom.name); // 報錯