One of my favorite math instructors taught me to challenge myself to solve my math problems in 3 ways: with a function, with a graph, and with a set of values. Now that JavaScript has 3 relatively recent versions, you can challenge yourself to solve problems in JavaScript using ES3, ES5, and ES6.

At first glance, it might not make sense to try using older versions of JavaScript, especially now that ES5 enjoys such high levels of support. But I think there’s still a lot of value in knowing how to read and use the syntax from old versions because our ecosystem of transpilers can sometimes hide the fact that the code we write isn’t always the code we use.

Let’s take a look at an ES3 version of flatten:

What I found interesting here is that Array.isArray() and Array.prototype.reduce() don’t exist yet. Without access to the ES5 Array improvements, JavaScript has a hard time revealing itself as a functional programming language.

The ES5 version of flatten will look much more familiar:

Having access to reduce makes the function much more compact, but now I miss my arrow functions.

Let’s see how ES6 can flatten (see this great article by Casey Morris):

Doesn’t that feel nice? Having access to arrow functions and the spread operator allows us to create code that minimizes syntax noise. Does it increase or decrease readability? I think it can be difficult to read at first, but I also realize that it represents a pattern that I can apply in a number of places.

The recursion technique is neat and all, but it might be a little too neat. As Ryan Dahl recently said “I regret trying to do cute things.” Let’s look at an ES6 example that just uses arrow functions:

This one ultimately feels the most expressive and readable to me.

Once I had a good idea of how I wanted to express my flatten variants, I set up a JSPerf test to see how they compare in terms of performance. After running the test a few times on Chrome 67, I found that the ES3 version was ever-so-slightly faster.

I guess this gives me something to think about when I’m targeting a run-time version of JavaScript for my transpilers!