关于它做什么的问题,请阅读所有评论和其他答案。他们是绝对正确的。
你为什么要使用它?在使用闭包时,您经常会发现这种模式。以下代码片段的目的是为 10 个不同的 DOM 元素添加一个事件处理程序,并且每个元素都应该提醒它的 ID 属性(例如,“你点击了 3 个”)。您应该知道,如果这是您的实际意图,那么有一种更简单的方法可以做到这一点,但出于学术原因,让我们坚持这个实现。
var unorderedList = $( "ul" );
for (var i = 0; i < 10; i++) {
$("<li />", {
id: i,
text: "Link " + i,
click: function() {
console.log("You've clicked " + i);
}
}).appendTo( unorderedList );
}
上面代码的输出可能不是你最初期望的。每个点击处理程序的结果都是“你点击了 9”,因为在事件处理程序被触发时 i 的值是“9”。开发人员真正想要的是在定义事件处理程序的时间点显示 i 的值。
为了修复上述错误,我们可以引入闭包。
var unorderedList = $( "ul" ), i;
for (i = 0; i < 10; i++) {
$("<li />", {
id: i,
text: "Link " + i,
click: function(index) {
return function() {
console.log("You've clicked " + index);
}
}(i)
}).appendTo( unorderedList );
}
您可以从 jsFiddle 执行和修改上述代码。
修复上述代码的一种方法是利用自执行匿名函数。这是一个花哨的术语,意味着我们将创建一个无名函数,然后立即调用它。这种技术的价值在于变量的范围保持在函数内。因此,首先我们将事件处理程序内容包围在一个函数中,然后立即调用该函数并传入 i 的值。通过这样做,当事件处理程序被触发时,它将包含定义事件处理程序时存在的 i 的值。
进一步阅读闭包:JavaScript 闭包的用例