背景:
- 理解閉包,必須首先要理解變量作用域,關于JavaScript的變量作用域,參見我之前的一篇文章《【JavaScript】變量作用域》
- JavaScript中的函數(shù)都是對象
簡而言之,JavaScript函數(shù)內部的所有變量對外部是不可見的
比如這樣的代碼會拋出error
var test = function() {
var i = 0;
}
console.log(i); // undefined
那么怎么讓函數(shù)訪問外部變量呢?
JavaScript擁有函數(shù)級的作用域,函數(shù)內部調用的函數(shù)可以訪問其外部函數(shù)的變量。所以我們可以在一個函數(shù)內部再調用一個函數(shù),這樣其內部函數(shù)就實現(xiàn)了訪問外部變量。這就是所謂的閉包。
閉包的好處是內部函數(shù)可以訪問定義它們的外部函數(shù)的參數(shù)和變量
閉包示例
var test = function(status) {
return {
getStatus: function(){
return status;
}
};
};
// 測試: 調用test時,它返回一個包含getStatus方法的新對象
var myQuo = test('404');
console.log(myQuo.getStatus());
另一個例子:構造一個函數(shù),當點擊一個節(jié)點時,輸出當前節(jié)點的編號
// 這是一個錯誤的例子,點擊任意節(jié)點輸出結果都為9
// 這個函數(shù)綁定了變量i本身,而不是函數(shù)在構造時變量i的值
var addHandlers = function(nodes) {
var i;
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = function(e) {
console.log(i);
};
}
};
正確的例子·
var addHandlers = function(nodes) {
var helper = function(i) {
return function() {
console.log(i);
};
};
var i; // 避免在循環(huán)中創(chuàng)建函數(shù)
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = helper(i);
}
}