Appearance
闭包
什么是闭包?
闭包允许函数访问并操作函数外的变量。只要变量或者函数存在于声明函数时的作用域内,闭包即可使函数能够访问这些变量和函数。
闭包的应用场景
1. 创建私有变量
javascript
function person() {
let money = 0;
return {
getMoney() {
return money;
}
work() {
money = money + 1000;
}
}
}
const p1 = new Person();
// 无法直接访问私有属性 money
console.log(p1.money) // -> undefined;
// 通过 getMoney 方法可以访问到私有变量 money
console.log(p1.getMoney()) // -> 0;
2. 回调函数
一个经典的代码示例
javascript
var list = document.createElement('ul');
for (var i = 1; i <= 5; i++) {
var item = document.createElement('li');
item.appendChild(document.createTextNode('Item ' + i));
item.onclick = function (e) {
console.log('Item ' + i + ' is clicked.');
};
list.appendChild(item);
}
document.body.appendChild(list);
这段代码的原意是想单击每个li
元素时,打印它们的编号,但实际上,无论单击哪一个li
,打印输出的都是Item 6 is clicked.
。
解决方案 1:使用闭包
javascript
item.onclick = (function (j) {
return function (e) {
console.log('Item ' + j + ' is clicked.');
};
})(i);
解决方案 2:使用 let
javascript
for (let i = 1; i <= 5; i++) {
// 省略
}
题外话
类似于这种需求,我们可以使用事件委托的机制做一个优化,仅仅给父元素添加一个事件监听器,而不是给每个子元素添加事件监听器。
参考资料
- 《JavaScript 函数式编程思想》潘俊
- 《JavaScript 忍者秘籍》