dmi*_*itq 8 javascript jquery closures loops for-loop
我正在使用jQuery,我有一个我不明白的奇怪的事情.我有一些代码:
for (i = 1; i <= some_number; i++) {
$("#some_button" + i).click(function() {
alert(i);
});
}
Run Code Online (Sandbox Code Playgroud)
正如名字所说的"#some_button" - 它们是一些按钮.点击它们时,应该弹出一个带有它号码的方框,对吗?但他们没有.如果有4个按钮,它们总是弹出"5"(按钮计数+ 1).为什么会这样?
Hoo*_*ing 18
它与JavaScript范围有关.您可以通过添加一个函数并让该函数调用自身并传入i来引入另一个范围,从而轻松解决它:
for (var i = 1; i <= some_number; i++) {
(function(j) {
$("#some_button" + j).click(function() {
alert(j);
});
})(i);
}
Run Code Online (Sandbox Code Playgroud)
这会创建一个闭包 - 当内部函数可以访问调用函数时不再存在的作用域时.有关更多信息,请参阅MDC上的这篇文章.
编辑:RE:自我调用函数:自调用函数是一个匿名调用的函数.您没有实例化它,也没有将它分配给变量.它采用以下形式(注意开头的parens):
(function(args) {
// function body that might modify args
})(args_to_pass_in);
Run Code Online (Sandbox Code Playgroud)
将此与问题联系起来,匿名函数的主体将是:
$("#some_button" + j).click(function() {
alert(j);
});
Run Code Online (Sandbox Code Playgroud)
将这些组合在一起,我们在第一个代码块中得到答案.匿名自调用函数期待一个名为的参数j.它查找id为some_button最后整数值的任何元素j(例如some_button1,some_button10).每次单击其中一个元素时,它都会警告其值j.解决方案的倒数第二行传入值i,即调用匿名自调用函数的循环计数器.换句话说,它可能看起来像这样:
var innerFunction = function(j) {
$("#some_button" + j).click(function() {
alert(j);
});
};
for (var i = 1; i <= some_number; i++) {
innerFunction(i);
}
Run Code Online (Sandbox Code Playgroud)
你在循环中遇到了一个非常常见的闭包问题for.
封闭在闭包中的变量共享相同的单个环境,因此在click调用回调时,循环将运行并且i变量将指向最后一个条目.
您可以使用函数工厂通过更多闭包解决此问题:
function makeOnClickCallback(i) {
return function() {
alert(i);
};
}
var i;
for (i = 0; i < some_number; i++) {
$("#some_button" + i).click(makeOnClickCallback(i));
}
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉闭包的工作方式,这可能是一个非常棘手的主题.您可以查看以下Mozilla文章以获得简要介绍:
| 归档时间: |
|
| 查看次数: |
1573 次 |
| 最近记录: |