什麼是閉包?javascript
「官方」的解釋是:所謂「閉包」,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(一般是一個函數),於是這些變量也是該表達式的一部分。css
通俗的講:就是函數a的內部函數b,被函數a外部的一個變量引用的時候,就建立了一個閉包。html
javascript語言的特別之處就在於:函數內部能夠直接讀取全局變量,可是在函數外部沒法讀取函數內部的局部變量。因此在要得到函數內部變量時,只能在函數內部再定義一個函數。java
因此說,閉包能夠簡單理解成「定義在一個函數內部的函數「。閉包
或者說兩種狀況:函數做爲返回值,函數做爲參數傳遞。函數
下面來三個最多見的閉包代碼:this
1.閉包計數spa
var add = function(){ var counter = 0; return function(){ return(++counter); } }; var a = add() var b = add() console.log(a()) // 1 console.log(a()) // 2 console.log(b()) // 1
2.閉包事件code
<p>文字1</p> <a href="javascript:void(0)">red</a> <a href="javascript:void(0)">green</a> <a href="javascript:void(0)">blue</a>
$('a').click(function(){ changeColor($(this).html())() }) function changeColor(color){ return function(){ $('p').css('color',color) } }
3.常見閉包陷阱htm
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]()); }
這段代碼輸出的是10個10 ,由於return i 是在函數執行時纔去取i的值的,這時候循環中的i已經變爲了10
兩種方法能夠把輸出結果改成0到9
一種是用將var i 換位let i
function createFunctions(){ var result = new Array(); for (let i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]()); }
另外一種是用當即執行函數,
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = (function(){ return i; })(); } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]); }