定義:閉包是指有權訪問另乙個函式作用域中變數的函式。
1、閉包與變數
作用域鏈的這種配置機制引出了乙個值得注意的***即閉包只能取得包含函式中任何變數的最後乙個值。
我們首先來看乙個很常見的場景
function createfunction()
}return result;
}
這個函式會反回乙個函式陣列。表面上看,似乎每個函式都應該返回自己的索引值,即位置0的函式返回0,位置1的函式返回1,以此類推。但實際上每個函式都返回10因為每個函式作用域鏈都儲存著createfunction()函式的活動物件,所以他們引用的都是同乙個變數i。這時候就需要閉包上場了,如果我們想要達到預期效果需要這麼寫
function createfunction() ;
}(i)
}return result;
}
這個版本寫法中我們沒有直接把閉包賦值給陣列,而是定乙個乙個匿名函式,並立即函式立即執行結果賦給陣列。這裡匿名函式有乙個引數num,也就是最終函式要返回的值。在呼叫匿名函式時我們傳入了變數i。由於函式引數是按值傳遞的,索引就會將變數i的當前值複製給num。而這個匿名函式內部,又建立並返回了乙個訪問num的閉包。這樣一來,result陣列中每個函式都有自己num變數的乙個副本,因此就可以返回不同的值了。
2、閉包中的this
閉包中使用this物件可能會導致一些問題。我們知道this物件是在執行時基於函式的執行環境繫結的:在全域性函式中,this等於window,而當函式被作為某個物件的方法呼叫時,this等於那個物件。我們來看下面的例子。
var name = "this window"
var object =
}}alert(oject. getnamefunc()()); // "this window"
不過如果把外部作用域中的this包存在乙個閉包能訪問到的變數裡,就可以讓閉包訪問該物件了。
var name = "this window"
var object =
}}alert(oject. getnamefunc()()); // "this window"
3、記憶體洩漏
具體來說,如果閉包作用域鏈中儲存著html元素,那麼就意味著該元素將無法銷毀。來看個例子
function assignhandler()
}
由於匿名函式儲存了乙個對assignhandler() 活動物件的引用,因此就會導致element的引用數最少也是1,因此它的記憶體永遠不會被收回。我們改寫成以下**就能解決
function assignhandler()
element = null;
}
通過element.id的乙個副本儲存在變數中,還是不能完全解決記憶體洩漏的。必須要記住:閉包會引用包含函式的整個活動物件,而其中包含著element。即使閉包不直接引用element,包含函式的活動物件仍然會儲存乙個引用。因此有必要把element設定為null。
4、模仿塊級作用域
es6之前只有全域性作用域和函式作用域是沒有塊級作用域概念的,但通過閉包可以在函式內模仿寫法如下
(function())()
下面是如何在函式內使用私有作用域
funtion outputnumbers(count)
})();
alert(i); // 導致乙個錯誤
}
談談對閉包的理解
說起閉包,讓很多新手頭疼的乙個概念,甚至於有一兩年js基礎的開發人員也沒有搞懂 說到閉包,要從js的作用域說起,js的變數是函式作用域,且變數不能被函式外部訪問,但是可以被函式內部的函式訪問.這稱為js鏈式作用域 1什麼是閉包?我的理解是,閉包就是能夠讀取其他函式內部變數的函式 function t...
說說js閉包
js閉包涉及到作用域,js的作用域有兩種,全域性變數和區域性變數,全家變數就是在函式外宣告的,區域性變數是在函式內宣告的,函式內部可以直接讀取全域性變數 但是函式外部自然無法讀取函式內的區域性變數 函式內部宣告變數的時候,要用var不然就是個全域性變數 有時候需要得到函式內的區域性變數 濫用閉包會可...
JS閉包理解
下圖例項 body ul li 1 li li 2 li li 3 li ul body html script vara document.getelementsbytagname li for vari 0 i a.length i i 如何從外部讀取區域性變數 functionvisitinn...