Javascript .forEach循环:使用变量

Javascript .forEach循环:使用变量,javascript,jquery,foreach,Javascript,Jquery,Foreach,我正在遍历一组16个ID,并为每个ID分配一个eventListener。我想向我的php文件发送一个数字(第一个id为1,第二个id为2,等等),但I似乎比我希望的更具动态性。每个id发送17 klasses.forEach(function(klass){ var svgElement = svgDoc.getElementById(klass); //get the inner element by id svgElement.addEventListener("mouse

我正在遍历一组16个ID,并为每个ID分配一个
eventListener
。我想向我的php文件发送一个数字(第一个id为1,第二个id为2,等等),但
I
似乎比我希望的更具动态性。每个id发送
17

klasses.forEach(function(klass){
    var svgElement = svgDoc.getElementById(klass); //get the inner element by id
    svgElement.addEventListener("mouseup",function(){
        $.ajax({
            type: "POST",
            url: "buildService.php",
            data: { "service" : i}
        }).done(function(msg){
            alert(lameArray[i]);
            $("#modalSpan").html(msg);
            $("#modmodal").modal();
        });
    });
    i++;
});
如何将每一个设置为特定的数字?我也试过:

var lameArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
...
data: { "service" : lameArray[i]}
试试这个:

klasses.forEach(function(klass){
    (function(i) {
        var svgElement = svgDoc.getElementById(klass); //get the inner element by id
        svgElement.addEventListener("mouseup",function(){
            $.ajax({
                type: "POST",
                url: "buildService.php",
                data: { "service" : i}
            }).done(function(msg){
                alert(lameArray[i]);
                $("#modalSpan").html(msg);
                $("#modmodal").modal();
            });
        });
    })(i);
    i++;
});

什么是
i
?问题是,
i
是一个全局变量,或者是一个在
forEach
循环之外的变量,因此当触发
mouseup
事件时,将使用该istant中的
i
值,而不是定义事件侦听器时的值

请注意,由于您使用的是forEach,因此回调函数实际上是通过第二个参数调用的,即计数器。因此,您可以使用:

klasses.forEach(function(klass, i) {
    ...
});
现在,
i
forEach
范围中的一个变量,用于您的目的。(
forEach
也使用第三个参数调用回调函数,即集合本身-
klasses

注意:因为您使用的是jQuery,所以应该使用更“类似于jQuery”的风格进行编码。因此,请按如下方式更改代码:

$.each(klasses, function(i, klass) {
    $("#" + klass).mouseup(function(){
        $.ajax({
            type: "POST",
            url: "buildService.php",
            data: {service: i + 1}
            ...
        });
    });
});

当需要迭代器索引时,不要使用forEach。并避免JQuery的。每个。这在绝大多数情况下是完全不必要的,它在每次迭代时都会触发回调函数,因此在IE中速度要慢得多。你可以用while编写一个完全懒惰/紧凑的循环

var outerI = klasses.length;

while(outerI--){
    (function(i){
        i+=1;//doesn't affect outerI and you wanted 1-length so we add one.
        //I would personally just add 1 but it also adds clarity to the example

        //crap inside your forEach loop but without the i++
    })(outerI)
}
发生了什么:您告诉事件侦听器从外部作用域引用i。所以无论我是什么,当那个事件开始时,你得到的是什么

解决方案:将i的值传递到一个函数的作用域中,在这个作用域中,它将成为一个局部变量。使用parens的业务只是一种懒惰的方式,它可以定义、评估和执行一个匿名函数,就像一个步骤。函数通过第一个参数进行求值(使其可触发),因此第二个参数集类似于您放入函数定义的内部“i”参数中的参数。通过将值传递给一个新的局部变量,基本上锁定了所需的值


注意while循环:while(0)的计算结果为false,停止循环。如果你想一想,这是很奇怪的,因为到1的长度比你想要的要小一倍。使用while(i--)但是我得到了求值,然后i被递减,所以在块内得到长度-1到0,这对于数组表示法来说是完美的。要在其他运算符命中i之前减小i,通常需要这样做--i,但它在惰性/高效while循环中很容易实现。

另一方面,您可以将代码中的第一行更改为
klasss.forEach(函数(klass,i){
为什么不使用for循环而不是forEach?Bergi是这么说的。如果你在每次迭代中都调用一个函数,那么你可以使用
forEach
,使用回调函数中的第二个参数作为计数器。@Bergi:首先,我使用了问题中的一部分代码。其次,我认为forEach有更友好的语法是的,我知道并非所有浏览器都支持forEach。@MaxArt:我知道,所以我添加了第一条注释。读取Javascript闭包属性。。。。