我遇到了一个问题,并没有完全理解为什么每次重新调用函数时事件处理程序中的“闭包”都没有被更新。
目前,我从输入字段中收集一个字符串,在一个对字符串进行加扰并返回新值的函数中运行它。然后我将新值存储在变量中。
之后,我在页面上有一个进度条,它在完成后触发“完成”事件并达到100%,然后弹出一个带有加扰字符串的模态弹出窗口和新字符串。
这是我的代码:
$('#decodeSub').on("click", function(ev){
if($("#cryptText").val() === ""){
alert("Please Enter a Decrypted Tweet");
} else {
ev.preventDefault();
var decodedTweet = decode('REGKFJHUMWBOAXCDPLSQIYZTNV', $("#cryptText").val());
$("#decode_form").fadeOut("fast");
$("#decode").fadeIn("fast");
$('#decode_progress').progressbar({
display_text: 'center',
use_percentage: false,
refresh_speed: 10,
done: function(ev) {
debugger;
$(".modal-body").append(decodedTweet).css('color', 'black');
$("#decodeNewTweet").fadeIn("slow");
$(".modal").modal("show");
}
});
}
});
注意,我创建了加扰字符串并将其存储在变量decodedTweet
中。然后在.progressbar({})
函数内部,一个对象作为参数传递。该对象包含一个“done”属性,该属性指向使用“decodingTweet”变量的函数。
点击事件第一次运行时,一切都按照我的预期运行。但是在第一次运行之后,decodedTweet
变量被正确更新,但在done
函数内部,形成了一个闭包,它保存了第一个被加扰的字符串的值。
我不是百分之百确定它为什么会这样。我“假设”它与在第一次调用后不再被编译的done函数有关,因此闭包会无限期地持续存在。我不明白为什么会这样,不应该编译完成函数并在进度条中的每个“完成”事件后再次运行?
我能够使用bind方法修复我的代码:
$('#decodeSubmit').on("click", function(ev){
if($("#encryptText").val() === ""){
alert("Please Enter a Decrypted Tweet");
} else {
ev.preventDefault();
debugger;
this.decodedTweet = decode('REGKFJHUMWBOAXCDPLSQIYZTNV', $("#encryptText").val());
$("#decode_form").fadeOut("fast");
$("#decode").fadeIn("fast");
$('#decode_progress').progressbar({
display_text: 'center',
use_percentage: false,
refresh_speed: 10,
done: function(ev) {
debugger;
$(".modal-body").append(this.decodedTweet).css('color', 'black');
$("#decodeNewTweet").fadeIn("slow");
$(".modal").modal("show");
}.bind(this)
});
}
});
我理解这段代码是如何工作的,但我仍然对为什么第一段代码无法正常工作感到困惑。特别是为什么每次调用“done”函数或传递新的“done”事件时都不会创建decodedTweet
变量的新闭包。