在for循环中创建闭包 - 我这样做了吗? [英] Creating closures within a for loop - am I doing this right?

查看:132
本文介绍了在for循环中创建闭包 - 我这样做了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很怀疑。在这里相当密集,但我无法弄清楚下面的代码到底发生了什么。



我想要做的是附加两个独立的处理程序一个领域的变化事件。每个处理程序都是通过循环数组并使用数组中的项来设置的,以便在运行时实现处理程序的输出 - 希望在查看示例代码时变得清晰。



代码如下:

  $(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]);
}

要了解循环,如果你没有创建一个闭包,请看:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆