在for循环中创建闭包 - 我这样做了吗? [英] Creating closures within a for loop - am I doing this right?
问题描述
我想要做的是附加两个独立的处理程序一个领域的变化事件。每个处理程序都是通过循环数组并使用数组中的项来设置的,以便在运行时实现处理程序的输出 - 希望在查看示例代码时变得清晰。
代码如下:
$(document).ready(function(){
//
//在页面上创建一些测试输入字段...
//
$('< br />')。insertAfter( $('body> *:last' ));
$('< input type =textname =t0id =t0value =/>')。insertAfter($('body> *:last' ));
$('< input type =textname =t1id =t1value =/>')。insertAfter( $('body> *:last' ));
//
//有问题的部分 - 对我来说至少...
//
var arr = new Array(1,2) ;
for(var a in arr){
//在此处使用Chrome控制台记录
console.log(##+ a);
$('#t0 ')。更改( function(){
console.log(>> + a)
});
}
});
<那么当我在第一个字段中添加一个值时,我希望发生的事情是从控制台内部(在Chrome中运行这些示例):
## 0
## 1
>> 1
>> 2
我得到的是:
## 0
# #1
>> 1
>> 1
I我希望传递给处理程序的函数会在 a
的值上形成一个闭包,我最终将两个函数绑定到处理程序,其中一个函数是 a
的值为 1
,其中 a
的值为 2
。
想法?
干杯 - kris
这里有两个大错:
首先,(a in x)的不能像你期望的那样工作:它迭代对象属性,而不是数组元素。
另一个错误是 a
在调用函数时发生了变化。实现所需功能的好方法是:
for(var a = 0; a< arr.length; a ++ ){
(函数(a){
//现在你可以使用a
})(arr [a]);
}
要了解对$的影响c $ c>循环,如果你没有创建一个闭包,请看:
var arr = [1,2,3 ]。
var functions = [];
for(var a = 0; a< arr.length; a ++){
functions.push(function(){
console.log(a);
})
}
//现在执行所有函数
for(var i = 0; i< functions.length; i ++){
functions [i ]();
}
现在所有功能都会记录 3
,这是数组中最后一个元素的索引+ 1( arr [0] == 1,arr [1] == 2,arr [2] == 3
)。会发生的是循环的在每次迭代时都会创建这些函数,但是在循环结束后,它们会在
之后执行 a == arr.length
。
I am prob. being pretty dense here but I can't figure out exactly what is going on in the code below.
What I am trying to do is attach two, separate, handlers to the change event of a field. Each handler is set up by looping over an array and using the items in the array to effect the output of the handler when it runs - hopefully will become clear when you look at the example code.
Code follows:
$(document).ready( function () {
//
// Create some test input fields on the page...
//
$('<br />').insertAfter($('body > *:last'));
$('<input type="text" name="t0" id="t0" value="" />').insertAfter($('body > *:last'));
$('<input type="text" name="t1" id="t1" value="" />').insertAfter($('body > *:last'));
//
// The problematic part - for me at least...
//
var arr = new Array(1, 2);
for (var a in arr) {
// Using Chrome console here for logging
console.log("## " + a);
$('#t0').change(function () {
console.log(">> " + a)
});
}
});
So what I would expect to happen when I add a value to the first field is, from within the console (running these examples within Chrome):
## 0
## 1
>> 1
>> 2
What I get is:
## 0
## 1
>> 1
>> 1
I would have expected the function passed to the handler would form a closure over the value of a
and I would end up with two functions being bound to the handler, one in which a
had the value 1
and one in which a
had the value 2
.
Ideas?
Cheers - kris
There are two big mistakes here:
First of all, the for (a in x)
doesn't work like you expect it to: it iterates over object properties, not over array elements.
The other mistake is that a
changes by the time the function gets called. A good way to achieve the desired functionality is like this:
for(var a=0; a<arr.length; a++) {
(function(a) {
// now you can use "a"
})(arr[a]);
}
To see what happens with the for
loop if you don't create a closure, see this:
var arr = [1,2,3];
var functions = [];
for(var a=0; a<arr.length; a++) {
functions.push(function() {
console.log(a);
})
}
// now execute all the functions
for(var i=0; i<functions.length; i++) {
functions[i]();
}
Now all the functions will log 3
, which is the index of the last element in the array + 1 (arr[0] == 1, arr[1] == 2, arr[2] == 3
). What happens is that the for
loop creates those functions at each iteration, but they get executed after the loop finishes, when a == arr.length
.
这篇关于在for循环中创建闭包 - 我这样做了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!