It is current year new Date().getFullYear(), and still I still see many JavaScript devs using and even recommending the use of for loops. You yours...
For further actions, you may consider blocking this person and/or reporting abuse
... And it's articles like this that make me think we were better off before anyone could publish anything on the internet.
The main problem I have is your piece is actually well written, thus it is probably going to be taken as gospel by newbie devs.
I enjoy the ease of writing callback functions instead of for loops as much as anyone, but it is such a biased outlook to claim that this is always the right solution.
Why don't you mention the areas where imperative loops outshine higher order functions? E.g. the fact that a for loop is ~10x faster than a
forEach
callbackI believe this is untrue. Can you substantiate this claim?
It's widely known that loops based on callback functions generally perform much worse than imperative loops. Here's an example, where
forEach
is 96% slower than a vanillafor
loop: stackoverflow.com/questions/438217...C'mon man, I appreciate that you want to share your knowledge, but if you are going to write posts with such provocative titles then you need to know this stuff. I am a big fan of functional programming and much prefer it over OOP, but the aspect I dislike most about FP is the performance hit from making everything immutable
Try yourself.
let arr = [];
for(x = 0; x < 100000; x++) {arr.push(Math.random());}
function oldFor(d) {
aux = [];
const t0 = performance.now();
for(x=0; x < d.length; x++) {
aux.push(d);
}
return (performance.now() - t0);
}
function eachFor(d) {
let aux = [];
const t0 = performance.now();
d.forEach(v => {
aux.push(v);
});
return (performance.now() - t0);
}
oldFor(arr);
eachFor(arr);
Okay. This is your code in typescript with a 10M length array. The forEach time is double.
I made another for just testing the other loops with a 10M length array.
So... the conclusion is... If you want to loop through big arrays just use the old for loop. And I made an account just for to send this comment.
wow, this is terrible. I'd suggest "deleting this post" if you were to ask.
The title is so clickbait, it can confuse people a lot.
Your examples are not about "stop using" but about situations how/when to use
filter
,reduce
, etc.I think you should provide more specific examples and real life use cases to explain your opinion, otherwise it's a really bad advice.
I would like to filter all those kind of articles.
To be clear I appreciate your effort, but radical attitudes saying that you should not use x or y is harmful. Lately there was such attitude for not using
reduce
, and I don't agree with that in the same way I don't agree with your article.Also I think you are by intention making such clickbait title.
Good one 😁
If you are working with very large lists of data, the for loop shines like a diamond
Or if you read a very big file, or a result set of unknown size.
+1 about
reduce
. Consider #3 in dev.to/thejohnstew/5-programming-p...It uses
reduce
to feel functional and hip, but in practice it just mutates the arrays and passing them as is (they are mutated, but it's the same reference) to the next iteration.But even proper uses of
fold
/reduce
are usually clearer and simpler when done with loops, because the whole point ofreduce
was to emulateforeach
in purely functional languages.All of these are tools that serve different purposes. A few points I'd like to make:
1.) Composition
The prototype methods
map
,filter
,reduce
are useful because they avoid side effects and mutation by returning a new instance of the array, but they're also composable (or chainable in this chase), arguably their biggest benefit.The other methods,
sort
,every
, andforEach
are either not composable because they don't turn arrays, or they actually does mutate in place (which you do touch on in the article with forEach, much appreciated, but sort is the bigger offender).2.) OG for loops are generally faster
hackernoon.com/javascript-performa...
Not only that, but they can take exponentially less resources. Imagine you have a data set of N objects, that all get mapped, filtered, and reduced via prototype methods. That's three new versions of your data of N length that have to be in memory now, and you've gone through the list 3 times. There're real performance implications to this. If you can do it with a for loop in one pass, that may be a better option in context.
3.) For...of
The new for...of operator is outstanding, and plays better with async/await than the array prototype methods. Take a composition function for example:
This is basically a reduce, but it is easier to understand and write with a for...of loop. Try an implement this with the reduce prototype method, and I think you will see that it's not as straightforward.
Not only that, but For...of's support iterables, one of JavaScript's most powerful features. To use Array prototype methods, you have to spread them across a new array and you lose the context about what the data structure was initially. You then lose all the benefits of them- whether it's a Set or Map or some custom iterable. To me, that's pigeonholing yourself to array features and JS will evolve past that.
Always appreciate a different opinion though. Thanks for writing this and starting the conversation!
I actually enjoyed your piece. I think you're getting piled on.
There are good reasons to use
.forEach()
,for
andwhile
. Just remember, withforEach()
it's just an abstraction - it's basically sugar on top of afor
loop. This makes it quite a bit slower, but I'd agree syntax is often much cleaner.Maybe unintentionally, you're veering into a larger discussion on performance and picking the right data structure to use in a given situation. You might want to follow this piece up with a part 2 where you analyze those further.
Agreed on most counts. You don't mention that
for
loops also allow you to break out of the loop early; which depending on context can provide performance benefits.On the contrary, there are some incredibly useful applications for
reduce
and it can often be used when a normalfor
loop seems like the only option.You can't use BREAK or CONTINUE in a foreach/filter/map etc. Normal for loops are there for a reason.
My point is that
for
loops shouldn't be the first solution, but rather used on a "as needed" basis. I acknowledge in my article there are circumstances where they may be preferable.Could you justify this statement?
One problem with using syntatic sugar like these are people recreating a callback on each call of a function that contains a
.map
,.forEach
or whatever.Also for loop is significantly faster and more readable in most cases, if you know how to do it correctly.
Note for beginners: If you want to get good, try to understand what's going on under the hood.
The blanket statement "stop using for loops" is just bad advice. There are plenty of times when they are the best solution, for instance when looping over a "stack" that can grow as you loop over it, see the following stack-overflow answer: stackoverflow.com/a/47889841/34806 Use them when they make sense, and don't use them when they don't, and if you don't know the difference, don't write posts about them
Nice article. You require for loops for situations where you have to adjust the current index of the loop or step by steps other than 1. Even when dealing with arrays, you don't always want to loop over the array item per item.
You raise a great point. As I said, sometimes you’ll have no choice but to use
for
loops. It’s up to us as devs to decide if and when they should be used. In the interest of minimising their use, it’s good to creatively explore alternatives.Adjusting index is a tricky one -- my understanding is that if you want to do that as part of something like a binary search, there’s no real alternative to
for
loops. If you expect small input sizes, you could get away withArray.prototype.indexOf()
: O(n) complexity vs O(log n) for a binary search.Iterating by steps other than 1 is a bit easier. You can do this by chaining
Array.prototype.filter()
andArray.prototype.forEach()
:Array.prototype.reduce()
also works. Yes,element
ends up being unused, but this is nonetheless preferable to using afor
loop.For loops are old school, and old school is sometimes still great :)
Plus all school books use only for loops in their examples anyway!
All of us who appreciate non-clickbait should make our own Wikipedia-like platform where any inaccurate or clickbait articles are immediately deleted.
Wow, that's so aggressive.
If I want clickbait titles I could open Medium and find hundreds of them. And it's very difficult to find a real useful article there. Do you want Dev.to to be same place?
You're right, dev.to is much better than medium. My comment here added no value to the discussion, apologies to OP.
I love this take. for loops are tough to read, albeit .forEach() is only slightly more readable. Most times for loops don't need to be replaced with forEach(), they can be replaced with a .map(), .filter(), etc and be much more readable, avoid mutation and allow your code to follow a more functional pattern. If you think your array methods are slowing down your app, consider swapping out with a traditional for loop, but i wouldn't pre-optimize this way at the expense of readability and maintainability. The key to web apps at scale is a maintainable code base which means its readable and intentions are clear. This allows team members to make changes quickly without fear of bugs.
Chances are that your array methods aren't what's making your app slow. Here are some common reasons your app is slow: netguru.com/blog/11-reasons-why-yo.... But, if you're dealing with a large data set, and the array methods are causing an unwanted delay, switch back to for loop.
So in summary: if there is a built in function to do what you want to do in your potential loop, then use it. That is, if someone else implemented your ugly for loop for you, then you don't need a for loop. If they did not, then...... what exactly? I have been programming for 20 years and have no idea what this discussion (that I've seen before on other sites) is actually about.
Stop saying things like this
Looks like you're getting a lot of heat here. But as a somewhat JS beginner it was nice to see the different array implementations compared to their respective loops.
Thanks for the write up.
The problem isn't the "different array implementations", title is the problem. Is intentionally bad to attract views, but send a wrong message.
.filter, .map, .sort are usefull tools, but FOR is better in terms of performarce. If you have a lot of data to process, FILTER will not be the best choice.
Nobody should stop using for loops.
for(;;){}
For loop for performance wise.
That looks alright with me!
This must be satire.