【问题标题】:.forEach loop: use variable.forEach 循环:使用变量
【发布时间】:2012-07-11 15:07:46
【问题描述】:

我正在遍历一组 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]}

【问题讨论】:

  • 读取 Javascript 闭包属性....

标签: javascript jquery foreach


【解决方案1】:

i 是什么?问题是i是一个全局变量,还是forEach循环之外的变量,所以当mouseup事件被触发时,thatistant中i的值是使用,而不是定义事件侦听器时使用的那个。

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

klasses.forEach(function(klass, i) {
    ...
});

现在,iforEach 范围内的一个变量,可以满足您的目的。 (forEach 也使用第三个参数调用回调函数,即集合本身 - 在您的情况下为 klasses。)

注意:由于您使用的是 jQuery,因此您应该使用更“类似 jQuery”的样式进行编码。所以改变你的代码是这样的:

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

【讨论】:

    【解决方案2】:

    试试这个:

    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++;
    });
    

    【讨论】:

    • 另一方面,您可以将代码中的第一行更改为klasses.forEach(function(klass, i){
    • 为什么不使用 for 循环而不是 forEach?
    • Bergi 所说的。如果你最终在每次迭代中调用一个函数,那么你可以使用forEach,使用回调函数中的第二个参数作为计数器。
    • @Bergi:首先,我使用了问题中的一部分代码。其次,在我看来,forEach 的语法比 for 循环更友好。是的,我知道并非所有浏览器都支持 forEach。
    • @MaxArt:我知道,所以我添加了第一条评论。
    【解决方案3】:

    在需要迭代器索引时不要使用 forEach。并避免使用 JQuery 的 .each。在绝大多数情况下它是完全没有必要的,它在每次迭代时都会触发一个回调函数,所以它在 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 的值传递到函数的范围内,在该函数范围内它成为本地 var。带括号的业务只是定义、评估和执行匿名函数的一种懒惰方式,看起来像是一步。该函数通过第一个括号进行评估(使其可触发),因此第二个集合就像您放入函数定义的内部“i”参数中的 arg。您基本上通过将其传递给新的本地变量来锁定您想要的值。

    关于 while 循环的注意事项:while(0) 的计算结果为 false,停止循环。如果您考虑一下,这很奇怪,因为长度为 1 比您想要的少一。使用 while(i--) 然而 i 被评估,然后 i 递减,所以在块内你得到长度 1 到 0,这对于数组表示法来说是完美的。要在其他运算符击中它之前减少 i,您通常会这样做 --i 但它在惰性/高效的 while 循环中很方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-17
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多