ECMA- / Javascripts Array.prototype.forEach

Javascript (ECMAscript) has supported the Array.prototype.forEach method since version 1.6 (ECMAscript edition 3, 2005). Thus, quite a few browsers already support this method, and it is incredibly fast compared to the jQuery $.each() method for example.
(In fact, it surpasses all implementations, regardless of which Javascript library)

Compared to jQuery, it is about 60-70% faster. Try it for yourself: forEach vs. jQuery on JSPerf.

The only drawback I have used so far is that I cannot figure out how early to break the iteration. Like for , while and do-while have a break statement, jQuerys .each() supports return false to break the loop.

I looked at the specifications of ECMAScript Edition 5 (the last thing I found), but they do not mention the early breakthrough of this cycle.

So the question is, can Mr. Douglas Crockford call this design error ?
Am I missing something and can I break such a loop early?

Edit

Thanks for the answers so far. I think that since no one came up with a β€œnative” solution, there really is no implementation for this (maybe a function?). In any case, I do not like the proposed methods, so I cheated a little and finally found the one I like (at least better). It looks like:

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

This is the "real" production code. I was looking for a good way to look for css3 conversion properties, and I got lost in ecma5 specifications and weird Javascript forums :-)

So, you can pass the array object as the third parameter to the .forEach . I create a copy from the original array by calling slice(0) and setting its .length property to 0 as soon as I found what I was looking for. It works well.

If someone comes up with a better solution, I will edit this, of course.

+4
source share
4 answers

Well, you can use every instead. The function is intended to return true if the provided callback function returns true (true) for each element in the array and false otherwise. The key point here is that as soon as the callback function returns a false value, every immediately returns false without iterating over the rest of the array. So just ignore the return value and treat every as forEach .

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

In this example, alert will only fire 3 times.

Of course, the big bar here is that you must return a true value if you want the loop to continue. In fact, if you don't return anything (undefined), the loop will stop. Alternatively, you can use some , which behaves in exactly the opposite way; immediately returns true when the callback function returns a true value and false if it never happens. In this case, return true will be your break statement. Back yes, but it saves you from having to return true just continue the loop.

Now, if you have performance, I would recommend using the usual for loop, since when calling functions that will add up very quickly with large arrays, there is significant overhead. Using native functions helps a little, but the overhead of re-invoking user-defined functions still exists and is not trivial. At least it was my experience, you should, of course, conduct your own testing.

+7
source

I would suggest that you have a piece of code that needs to be run for each individual element. Do not use forEach to find an element or similar stop in the middle operation. Apply this function to each element of the array.

You could (I think) use some kind of global indicator to check and return false if "found" or something like that.

 var found = false; array.forEach(function (k, v) { if (found) { return false; } else { if (v == 1) { found = true; } } }); 
+1
source

You can throw an error to exit the iteration:

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

This is not entirely beautiful. I agree - specification error.

+1
source

I think I would use some other construct if I want the loop to be executed for a search.

The ability to exit forEach-ing mode is, of course, throw something, although in reality it is not the way we would like to use throw ...

0
source

All Articles