4

Javascript (ECMAscript)Array.prototype.forEach从版本 1.6 (ECMAscript edition 3, 2005) 开始支持该方法。因此,相当多的浏览器已经支持该方法,并且与 jQuery 的$.each()方法相比,它的速度非常快。
(实际上它击败了所有的实现,不管是哪个 Javascript 库)

与 jQuery 相比,它的速度大约快 60-70%。在 JSPerf上的forEach 与 jQuery上自己尝试一下。

到目前为止,我使用它的唯一缺点是,我无法想办法尽早中断迭代。Like for, whileand do-whilehave a breakstatement, 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)并将其属性设置为 0。.length效果很好。

如果有人提出更好的解决方案,我当然会编辑它。

4

4 回答 4

7

好吧,你可以every改用。true如果提供的回调函数true为数组中的每个元素返回(真实),则该函数旨在返回,false否则返回。这里的关键点是,一旦回调函数返回一个错误的值,every立即返回false而不迭代数组的其余部分。因此,只需忽略返回值,并将every其视为forEach.

[1, 2, 3, 4, 5].every(function(e) {
   alert(e);

   if (e > 2) return false; //break

   return true;
});

在本例中,alert只会触发 3 次。

Of course the big cavet here is that you must return a truthy value if you want the loop to continue. In fact if you return nothing (undefined) the loop will stop. Alternativly, you could use some which behaves in the exact opposite manner; immediatly returns true when the callback function returns a truthy value and false if it never does. In this case, return true would be your "break" statement. Backwards yes, but it saves you from having to return true simply to have the loop continue.

Now, if you are concerened with performance, I'd recomend just using a normal for loop, as there is significant overhead incurred when calling functionas that will add up very quickly with larger arrays. Using native functions helps somewhat, but the overhead of repeated calls to user-defined functions still exists and is non-trivial. At least this has been my experience, you should of course do your own testing.

于 2010-10-19T22:08:21.113 回答
1

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

您可以(我认为)使用某种全局指标来检查并在“找到”或其他情况下返回 false。

var found = false;
array.forEach(function (k, v) { 
    if (found) 
    { 
        return false; 
    } 
    else 
    { 
        if (v == 1) 
        { 
            found = true; 
        }
    } 
}); 
于 2010-10-19T19:57:26.083 回答
1

您可能会抛出错误以中断迭代:

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

这并不完全漂亮。我同意——规范错误。

于 2010-10-19T20:11:12.913 回答
0

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

突破 forEach-ing 的一个选项当然是throw某些东西,尽管这并不是人们真正想要使用 throw 的方式......

于 2010-10-19T20:10:46.443 回答