javascript - 这两个闭包有什么区别?
问题描述
我最近了解到有几种方法可以创建一个闭包(不仅仅是从函数中返回一个函数),而且还可以在事件侦听器中将函数引用为回调。这也创建了一个闭包,它解释了为什么即使在IIFE完成执行并且没有返回任何内容之后,您也可以使用 eventListener 调用 innerFunction。
我喜欢认为闭包的主要功能在于它不仅可以在外部函数中找到一个变量以在内部函数中使用,而且还可以更新它的值以便可以存储它。例如,您可以推入一个数组并在外部函数内部对其进行更新,或者将分数集更新为外部函数的基元。
但是,如果您可以通过事件侦听器引用函数来创建闭包,那么为什么不能在每次通过事件侦听器调用函数时更新局部变量,请参阅下文了解我想要了解的内容。
function increaseScore(){
var score = 0;
score ++;
console.log(score); // console.logs one everytime the event occurs
// despite the event listener creating a
// closure for this funciton
}
document.addEventListener("click", increaseScore);
function addScore(){
var score = 0;
return function (){ // This too is a closure created in a different way
// and increases every time the event is called
score ++;
console.log(score); // 1, 2, 3, 4, etc. every time the event occurs
}
}
var keepScore = addScore();
document.addEventListener("click", keepScore);
为什么会这样?它们都是闭包的例子,一个通过事件监听器,另一个通过返回函数,但只有返回函数的函数从其原始值零更新,并在每次调用函数时保存在内存中函数每次都重置为零,因此只会将 1 打印到控制台。我在任何地方都找不到解释。
解决方案
第一个不是闭包,因为在函数var score
中声明。一旦将该行移到函数之外,它将按预期工作(并且该函数将关闭全局变量):
var score = 0;
function increaseScore(){
score ++;
console.log(score);
}
document.addEventListener("click", increaseScore);
如何创建闭包而不使用return
它们的更好示例可能是
var keepScore;
function addScore(){
var score = 0;
keepScore = function (){ // this too is a closure
score++;
console.log(score);
};
}
addScore();
document.addEventListener("click", keepScore);
function addScore(){
var score = 0;
function keepScore(){ // this too is a closure
score++;
console.log(score);
};
document.addEventListener("click", keepScore);
}
addScore();
推荐阅读
- javascript - 将字符串化数字转换回数字
- r - 如何预安装运行您创建的包所需的 r 包?
- android-studio - 如何在 Android Studio 上使用 HotReload,使用手机设备进行调试
- ruby-on-rails-4 - 如何使用授权用户向具有相同 ldap 授权的另一个项目发出请求?
- maven - 在 ec2 (AWS) 上获取本地安装的 maven 依赖项的最佳方法是什么?
- windows - Windows 10 默认系统字体
- android - Android 约束布局未按预期工作
- python - 我无法绘制 dat 文件
- ngrx - 没有 subscribe() 就不会触发选择器
- python - 如何将数组作为变量存储在字典中