Java闭包的实际用途?
闭包是函数和在其中声明该函数的词法环境的组合。
function outerFunc() {
var name = "nhooo"; // name is a local variable created by outerFunc
return function innerFunc() {
// innerFunc() is the inner function, a closure
console.log(name); // use variable declared in the parent function
};
}
let f = outerFunc();
f()outsideFunc()创建一个名为name的局部变量和一个名为的函数innerFunc()。该innerFunc()函数是在内部定义的内部函数,outerFunc()仅在outerFunc()函数主体内可用。
请注意,该innerFunc()函数没有自己的局部变量。但是,由于内部函数可以访问外部函数innerFunc()的变量,因此可以访问在父函数中声明的变量名outerFunc()。
您可以看到,outerFunc完成执行后,该名称已超出范围。但是,如果仔细观察,返回并分配给f的innerFunc仍然可以访问name变量。因此,内部函数在outerFunc的词法范围内形成了一个闭合。
实际用途
模拟私有方法-Java之类的语言提供了将方法声明为私有的能力,这意味着它们只能由同一类中的其他方法调用。JavaScript没有提供执行此操作的本机方法,但是可以使用闭包来模拟私有方法。
示例
var counter = (() => {
var privateCounter = 0;
let changeBy = (val) => privateCounter += val;
return {
increment: () => changeBy(1),
decrement: () => changeBy(-1),
value: () => privateCounter
};
})();
console.log(counter.value());
counter.increment();
counter.increment();
console.log(counter.value());
counter.decrement();
console.log(counter.value());输出结果
0 2 1
与事件处理程序一起使用
for(let i = 0; i < 4; i++) {
button = buttons[i]
button.addEventListener("click", alert(i))
}如果在集合按钮中有4个按钮,并尝试添加这样的事件侦听器,则对这些按钮的任何单击最终都将给出未定义的结果。这是因为当它们被调用时,我将不再被定义。解决此问题的方法是在i上引入闭包。
for(let i = 0; i < 4; i++) {
button = buttons[i]
button.addEventListener("click", () => alert(i))
}