Stop using Array.forEach for everything! “for/of”, USE IT!

Image for post
Image for post

For some time I’ve been bothered by how people are introducing all sorts of unnecessary headaches in their code with . This has only been exacerbated through anonymous functions, particularly the painfully cryptic and oft outright stupid and pointless “Arrow Functions”. I’m seeing code all the time now where scoping issues, code clarity, and a host of other problems are all introduced by people overthinking the simplest of coding logic.

For example, I keep seeing code like this in actual deployment:

var company = {
name : 'Dunder Muffin',
employees : 'Pam', 'Jim', 'Andy', 'Kelly',
showEmployees : function() {
this.employees.forEach(
employee => console.log(this.name + ': ' + employee)
)
}
}

What’s wrong with that you ask? Four calls to a function for nothing, needing arrow functions to get around scoping issues you shouldn’t even have in the first place, and a lack of code clarity. Why not just:

var company = {
name : 'Dunder Muffin',
employees : 'Pam', 'Jim', 'Andy', 'Kelly',
showEmployees : function() {
for (var employee of this.employees) {
console.log(this.name + ': ' + employee;
}
}
}

Every time you call a function regardless of programming language, you introduce a LOT of overhead. Those of us who still work in assembly understand this as there’s a general process that all languages have to do to call a function.

Typically — and I’m oversimplifying here — when a function call is made the current program state — including the program counter — has to be saved onto the “stack”, a section of memory reserved for … well, saving things. Then any arguments / parameters / whateverNameIsHotAndTrendyThisWeek also either have their values, or pointers to their values, pushed onto the stack. Only then can the program counter — A pointer to where the current code is being executed — be changed to that of the function. When the function exits it has to de-allocate and restore all those values when it does the return.

That’s anywhere from four to ten steps — depending on language implementation — that could have been avoided if you skip using the function.

Hence executes many many times slower than a simple loop. With a “for/of” You’re not juggling memory around on every iteration, triggering garbage collection (if what JS has can even be called that) prematurely, and best of all you know where your bloody scope is!

Something similar can also be done in legacy browsers. Rather than polyfilling and then using a conventional function — since arrow functions crash IE outright by their mere presence — you can simply:

for (
var i = 0, employee;
employee = this.employee[i];
i++
) {

Assuming all Array-like entries are non-”loose false”. Remember, all assignments also “return” a value you can perform operations on. If you have something like a nodeList or other array-like you know have no loose-false entries, this is actually the fastest way to loop.

If we couldn’t operate on assignments, there’d be no need to distinguish betwixt and

It also works on all array-likes, unlike .forEach where I’ve seen people jump through hoops of fire to try and typecast their Array-like structures to Array. If you have false, zero, or other loose false values, simply:

for (
var i = 0, employee;
undefined !== (employee = this.employee[i]);
i++
) {

This might look like it should be slower, but if you access more than once in your actual codebase, storing it in the variable is faster as is the operation by comparison. This is the for structure most of us SHOULD be using client-side and it’s scary how many don’t, or have never even seen its possible.

Laugh is that whilst these varying ‘old school’ methods look like more code, they often are not.

Seriously, with “for/of” on the table for server-side operations, “for by assignment” available if you need indexing, and “for/in” for object iteration, is a sloppy, unnecessary, and problem inducing structure. It is in by no means an improvement upon the language. The same goes for a LOT of other callback-based methodology where people are using it for everything applying the technique with a paint roller instead of an eye-dropper.

Newer isn’t always better.

Now I’m NOT saying don’t ever use callbacks or methods like Array.forEach altogether! Again, don’t blanket statement things. Right tool for the right job. Just stop using them for short snippets you don’t re-use, in places where it introduces scoping headaches, when there are cleaner/simpler answers to the problem. THINK before you code! Learn all the different ways of doing things so you can pick the right one, instead of learning just one way and then assuming it’s the answer to every problem.

There are plenty of cases where these various “action by callback” make sense. You might have the same function/functionality looped in multiple different places, so a static function would make sense so the callback overhead is there anyways. But in any case where you’d pass these iterators an anonymous function? That’s when these methods become an instant epic /FAIL/ at web development. Particularly when any browser that supports these callbacks and “arrow functions” would have “for/of” available as well.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store