DEV Community

Discussion on: Why you should use Array.some instead of 'for' loop or forEach?

Collapse
 
psiho profile image
Mirko Vukušić • Edited

Hm, it is a nice introduction to array.some() but I don't think it's completely explained and some might pull wrong conclusions from this. Using "for" cannot be considered "wrong", especially not with explanation of why it would be wrong: "The problem with this approach is, this is not the right way to solve this problem.". So, it is wrong because it is wrong?

To be specific about array.some(), yes, it's hard to beat it in speed and simplicity. But it's also not hard to match it (in speed). What is left in that case is readability and simplicity of the code which makes it a clear winner in your example.
However, some might think that all of those "new" methods are always better and that "for" is incorrect, and that is not true. More often than not, new methods win in simplicity and readability but sacrifice speed. For most cases, speed difference is so small that it is unimportant, but when dealing with large arrays (and/or process them often), faster solution beats readable solution.

And again, it's not difficult to match "new" methods with "old" for-loops when it comes to speed. In fact, I don't know of a single case when you cannot match it with for-loops. New methods are never faster, they're just equally fast at best, and quite often... slower. So, for some performance oriented system, it's actually easier to always use for-loops and stop thinking if some of new methods is slower or equally fast... you just can never loose with for-loop in this case.

What I'm trying to say is that performance vs readability is not mentioned at all here, and naming "for" solution simply "wrong" is incorrect in my opinion. But yes, if you just don't need/want to care about performance then article is completely correct.

Example (benchmark) how to match performance of some() (and how NOT to try and match it) is here: jsbench.me/3ykr5dwv5l/1
It also serves as a good advocate to some(), because you can see it's highly optimized. i++ cannot beat it! You have to know about i-- trick to save that extra 7% (at least in Chrome)

Collapse
 
mazentouati profile image
Mazen Touati

I think some is confusing when introduced alone like in this article. It would be insightful if it's coupled with the contrasting function every.

I would like to add to what you've said that these all new methods are just new built-in functions in the Array's prototype. They are not language constructs. Hence, the looping constructs (for, while, etc.) have to be used anyway behind the scene.

Collapse
 
sannajammeh5 profile image
Sanna Jammeh

Behind the scenes V8 does not compile forEach, map, reduce etc to a for loop and then executes. It has its very own implementation within the runtime at the lowest possible level.

Only for polyfills where the engine does not have an implementation will you see a behind the scenes "for" or "while" loop.

Thread Thread
 
mazentouati profile image
Mazen Touati

Thank you for bringing this up. Indeed, V8 pre-compiles it to bytecode to enhance performance and to optimize memory usage. My comment made it sound like they're some kind of a library written in JS and being imported to your code to add new functions to the Array's protytpe. That's what I was thinking to be honest. After checking, it turns out V8 uses its own language V8 Torque and pre-compiles it to bytecode. Here's Array.some source code for example.

However, what I've tried to say is that it has to loop through the items at some point (even in the lowest level). Also, These optimations are not exclusive to the built-in functions. V8 will optimize your code too. For instance, most of the benchmarks I've consulted state that native for loops are faster than forEach, reduce, map etc.

The whole point was to point out that using For loops is not a wrong approach unlike what's being said in this Article.

Collapse
 
luk492 profile image
Luka Kajtes

I totally agree with your comment. Plus this is the polyfill for the "some" implementation. Good old for, just sayin...

if (this == null) {
  throw new TypeError('Array.prototype.some called on null or undefined');
}

if (typeof fun !== 'function') {
  throw new TypeError();
}

var t = Object(this);
var len = t.length >>> 0;

for (var i = 0; i < len; i++) {
  if (i in t && fun.call(thisArg, t[i], i, t)) {
    return true;
  }
}

return false;
Enter fullscreen mode Exit fullscreen mode