代码之家  ›  专栏  ›  技术社区  ›  jAndy

ECMA-/Javascripts Array.prototype.forEach

  •  4
  • jAndy  · 技术社区  · 15 年前

    Javascript(ECMAscript)支持 Array.prototype.forEach 方法自1.6版(ECMAscript版本3,2005)起。所以很多浏览器已经支持这种方法了,与jQuery相比,它的速度非常快 $.each() 例如方法。
    (实际上,它胜过所有实现,不管是哪个Javascript库)

    与jQuery相比,它大约快60-70%。你自己试试 forEach vs. jQuery 关于JSPerf。

    到目前为止,我使用它的唯一缺点是,我无法想出一种方法来提前中断迭代。就像 for , while 和 do-while 有一个 break 语句,jQuerys .each() return false 打破循环。

    ECMAScript第5版规范

    所以,问题是,道格拉斯·克罗克福德先生会称之为 design error ?
    我是不是错过了什么,有可能早点打破这种循环?

    谢谢你到目前为止的回答。我想既然没有人提出“本机”解决方案,那就真的没有实现(也许是一个特性?)。不管怎么说,我不太喜欢这些建议的方法,所以我胡闹了一会儿,终于找到了一个我喜欢的方法(至少,更好)。看起来像:

    var div     = document.createElement('div'),
    divStyle    = div.style,
    support     = jQuery.support,
    arr         = ['MozTransform', 'WebkitTransform', 'OTransform'];
    
    arr.slice(0).forEach(function(v,i,a){    
        if(divStyle[v] === ''){
           support.transform = v;
           a.length = 0;
        }
    });
    

    这是“真实”的生产代码。我寻找了一种查找css3转换属性的好方法,但在ecma5规范和怪异的Javascript论坛中迷失了方向:-)

    因此,可以将数组对象本身作为第三个参数传递到 .forEach 回拨。我从原始数组创建一个副本,调用 slice(0) 把它 .length 属性设置为0,只要我找到要查找的内容。效果很好。

    如果有人想出更好的解决方案,我当然会修改。

    4 回复  |  直到 15 年前
        1
  •  7
  •   MooGoo    15 年前

    好吧,你可以用 every 相反。函数的目的是返回 true 如果提供的回调函数返回 真的 false 否则。这里的关键是一旦回调函数返回一个错误的值, 立即返回 假 每一个 好像是 forEach .

    [1, 2, 3, 4, 5].every(function(e) {
       alert(e);
    
       if (e > 2) return false; //break
    
       return true;
    });
    

    在这个例子中, alert

    当然这里最大的问题是你 必须 如果希望循环继续,请返回truthy值。实际上,如果不返回任何内容(未定义),则循环将停止。另外,你可以用 some return true 会是你的“分手”声明。向后看是的,但它可以避免你不得不 返回真值 只是让循环继续。

    现在,如果你对性能感兴趣,我建议你只使用一个普通的 for

        2
  •  1
  •   lonesomeday    15 年前

    您可以抛出一个错误以从迭代中中断:

    if (typeof BreakIteration == "undefined") {
      BreakIteration = new Error("BreakIteration");
    }
    
    try {
        [0,1,2,3,4].forEach(function(key, value) {            
            console.log(key + ': ' + value);
    
            if (value == 3) {
                throw BreakIteration;
            }
        });
    } catch (error) {
        if (error !== BreakIteration) {
            throw error;
        }
    }
    

    这可不太好看。我同意——规格错误。

        3
  •  1
  •   Josh K    15 年前

    我假设您有一段代码需要针对每个元素运行。不使用 forEach 查找元素或类似的“中间停止”操作。将此函数应用于数组中的每个元素。

    你可以(我认为)使用某种全局指示符来检查,如果“找到”或其他什么东西,则返回false。

    var found = false;
    array.forEach(function (k, v) { 
        if (found) 
        { 
            return false; 
        } 
        else 
        { 
            if (v == 1) 
            { 
                found = true; 
            }
        } 
    }); 
    
        4
  •  0
  •   npup    15 年前

    我想如果我想循环搜索的话,我会使用其他的构造。

    当然,一个跳出困境的选择是 throw

    推荐文章