DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript基礎知識 >> JS閉包的理解特性詳解
JS閉包的理解特性詳解
編輯:JavaScript基礎知識     
閉包的結構有如下2個特性

1.封閉性:外界無法訪問閉包內部的數據,如果在閉包內聲明變量,外界是無法訪問的,除非閉包主動向外界提供訪問接口;

2.持久性:一般的函數,調用完畢之後,系統自動注銷函數,而對於閉包來說,在外部函數被調用之後,閉包結構依然保存在

系統中,閉包中的數據依然存在,從而實現對數據的持久使用。

缺點:

使用閉包會占有內存資源,過多的使用閉包會導致內存溢出等.

如下代碼:

function a(x) {
var a = x;
var b = function(){
return a;
}
return b;
}
var b = a(1);
console.log(b()); // 1

首先在a函數內定義了2個變量,1個是存儲參數,另外一個是閉包結構,在閉包結構中保存著b函數內的a變量,默認情況下,當a函數調用完之後a變量會自動銷毀的,但是由於閉包的影響,閉包中使用了外界的變量,因此a變量會一直保存在內存當中,因此變量a參數沒有隨著a函數銷毀而被釋放,因此引申出閉包的缺點是:過多的使用閉包會占有內存資源,或內存溢出等肯能性;

// 經典的閉包實列如下:
function f(x){ //外部函數
var a = x; // 外部函數的局部變量,並傳遞參數
var b = function(){ // 內部函數
return a; // 訪問外部函數中的局部變量
};
a++; // 訪問後,動態更新外部函數的變量
return b; // 返回內部函數
}
var c = f(5); // 調用外部函數並且賦值
console.log(c()); // 調用內部函數,返回外部函數更新後的值為6


下面我們來看看如下使用閉包的列子

在如下代碼中有2個函數,f函數的功能是:把數組類型的參數中每個元素的值分別封裝在閉包結構中,然後把閉包存儲在一個數組中,並返回這個數組,但是在函數e中調用函數f並向其傳遞一個數組["a","b","c"],然後遍歷返回函數f返回數組,我們運行打印後發現都是c undefined,那是因為在執行f函數中的循環時候,把值雖然保存在temp中,但是每次循環後temp值在不斷的變化,當for循環結束後,此時temp值為c,同時i變為3,因此當調用的時候 打印出來的是temp為3,arrs[3]變為undefined;因此打印出 c undefined

解決閉包的缺陷我們可以再在外面包一層函數,每次循環的時候,把temp參數和i參數傳遞進去 如代碼二

// 代碼一
function f(x) {
var arrs = [];
for(var i = 0; i < x.length; i++) {
var temp = x[i];
arrs.push(function(){
console.log(temp + ' ' +x[i]); // c undefined
});
}
return arrs;
}
function e(){
var ar = f(["a","b","c"]);
for(var i = 0,ilen = ar.length; i < ilen; i++) {
ar[i]();
}
}
e();
// 代碼二:
function f2(x) {
var arrs = [];
for(var i = 0; i < x.length; i++) {
var temp = x[i];
(function(temp,i){
arrs.push(function(){
console.log(temp + ' ' +x[i]); // c undefined
});
})(temp,i);
}
return arrs;
}
function e2(){
var ar = f2(["a","b","c"]);
for(var i = 0,ilen = ar.length; i < ilen; i++) {
ar[i]();
}
}
e2();
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved