閉包是指有權訪問另一個函數作用域中變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
閉包的特性:
1.函數內再嵌套函數 2.內部函數可以引用外層的參數和變量 3.參數和變量不會被垃圾回收機制回收
//li節點的onclick事件都能正確的彈出當前被點擊的li索引 <ul id="testUL"> <li> index = 0</li> <li> index = 1</li> <li> index = 2</li> <li> index = 3</li> </ul> <script type="text/javascript"> var nodes = document.getElementsByTagName("li"); for(i = 0;i<nodes.length;i+= 1){ nodes[i].onclick = (function(i){ return function() { console.log(i); } //不用閉包的話,值每次都是4 })(i); } </script>
執行say667()后,say667()閉包內部變量會存在,而閉包內部函數的內部變量不會存在
使得Javascript的垃圾回收機制GC不會收回say667()所占用的資源
因為say667()的內部函數的執行需要依賴say667()中的變量
這是對閉包作用的非常直白的描述
function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; } var sayAlert = say667(); sayAlert()//執行結果應該彈出的667
某段dom結構如下:在該dom結構中,li在列表的下標分別是0,1,2,3,4.請分別為每個li添加點擊事件,輸出響應的下標,注意:使用原生的js,且只能添加事件不能添加屬性.
<ul id="list"> <li>qw</li> <li>er</li> <li>ty</li> <li>ui</li> <li>ou</li> </ul> var lis = document.querySelectorAll('li'); //閉包實現 for (var i = 0; i < lis.length; i++) { lis[i].onclick = (function (j) { return function () { console.log(j); } })(i); } //forEach實現 lis.forEach(function (v, i) { v.onclick = function () { console.log(i); } }) //ES6實現 for(let i=0;i<lis.length;i++){ lis[i].onclick=function(){ console.log(i); } }