背景:
- 理解闭包,必须首先要理解变量作用域,关于JavaScript的变量作用域,参见我之前的一篇文章《【JavaScript】变量作用域》
- JavaScript中的函数都是对象
简而言之,JavaScript函数内部的所有变量对外部是不可见的
比如这样的代码会抛出error
var test = function() {
var i = 0;
}
console.log(i); // undefined
那么怎么让函数访问外部变量呢?
JavaScript拥有函数级的作用域,函数内部调用的函数可以访问其外部函数的变量。所以我们可以在一个函数内部再调用一个函数,这样其内部函数就实现了访问外部变量。这就是所谓的闭包。
闭包的好处是内部函数可以访问定义它们的外部函数的参数和变量
闭包示例
var test = function(status) {
return {
getStatus: function(){
return status;
}
};
};
// 测试: 调用test时,它返回一个包含getStatus方法的新对象
var myQuo = test('404');
console.log(myQuo.getStatus());
另一个例子:构造一个函数,当点击一个节点时,输出当前节点的编号
// 这是一个错误的例子,点击任意节点输出结果都为9
// 这个函数绑定了变量i本身,而不是函数在构造时变量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; // 避免在循环中创建函数
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = helper(i);
}
}