Photo by Markus Spiske on Pexels

A few days ago I was going through some old files on my computer and I’ve found, to my surprise, a lot of old code that I’ve written way back. One of the folders that I’ve found was filled with files of different algorithms and when I’ve opened one of them I’ve noticed a syntax that I haven’t used in quite a while — it was good old ES5 JavaScript. And I thought it would be really interesting to take one of them and introduce some modern JavaScript.

I’ve picked a really basic sorting algorithm — selection sort, that way we can focus more on code itself and not the idea behind it

(although if you’re not familiar with selection sort you’ll benefit from this article even more!).

Note: The changes that we’re making do not make the code “better” or “worse” necessarily, the point of the article is to introduce new syntax and new concepts, so some of the updates might look a bit arbitrary.

Selection sort

If you’re comfortable with selection sort you can definitely skip this section, otherwise I highly recommend reading it. The algorithm itself is fairly uncomplicated. The idea behind selection sort is finding the minimum element and putting it into the beginning of the array by swapping the current iterative value with the minimum value. With each and every iteration we’re getting almost two separate sub arrays, sorted and unsorted. Let’s look at an example with the following array:

array = [50, 20, 3, 6, 12]

Our first iterative value will be 50 and we want to find the lowest value forward (in our case it’s 3) and swap it 50. After the first iteration our array should look like this:

[3, 20, 50, 6, 12] // Two swapped values are 50 and 3

That gives two partitions of the array, sorted and unsorted. Let’s do another iteration, that way it will be easier to see those partitions. Our iterative value will be 20 and the lowest value forward would be 6. That’s the swap that we make.

array = [3, 6, 50, 20, 12] // Two swapped values are 20 and 6

After two iterations we can see that we have two partitions of the array, one sorted and one unsorted. The numbers in bold are sorted:

array = [3, 6, 50, 20, 12] // 50, 20, 12 is left unsorted

Then we repeat the iteration one more time. Our iterative element is 50 and the lowest value forward is 12, make the swap:

array = [3, 6, 12, 20, 50] // Two swapped values are 50 and 12

And at this point our iterative element is 20, which is the lowest value already, so we don’t need to swap it anymore and we get a perfectly sorted array.

Code in ES5:

And now let’s try rewriting this piece of code with the use of modern JavaScript!

Variables (const, let)

I’m going to cheat a little bit. Our current function is declared, but I’m going to rewrite it as a function expression and assign it to a constant variable called selectionSort . It will look something like this:

const selectionSort = function (arr) {…}

Now why would we want to use const instead of var ? The answer is simple, const prevents variable re-assignment. If you try to re-assign a value declared as const you’ll get an error. Don’t believe me?

Also, although const is hoisted, it is not initialized:

let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.

That means when you’re trying to access a variable before declaration using const or let you’ll get an error. Just try it out yourself, open the console and execute the following code:

{

console.log(hello);

var hello;

}

You probably didn’t get an error. Now execute the same piece of code, but swap var with const or let . If you’re using chrome you’ll see this lovely message:

Another benefit of const and let is that they’re both block-scoped. That means when you declare them in a block they will only be valid for that block. Let’s try it out once again. Open your console and paste this piece of code:

{

var notBlockScoped = ‘hello’

}

If you try to access it after the block you’ll surely get the value back.

Now again swap the var with let or const . What did we get?

Ah, that’s right. It’s not defined. You can see how this helps preventing bugs, as the variables do not leak out to the outer context. What we’ll do is we’ll change all of our var to be let and const because of all the benefits that they offer. Use const when you don’t want variable re-assignment and let if you want to change the value later on.

Info on let and const if you’d like to know more.

Arrow functions

Let’s use an arrow function to compact our function expression just a tiny bit more. We’ll go from this:

const selectionSort = function (arr) {…}

To this:

const selectionSort = arr => {...}

You can probably tell that we lost the parenthesis along the way as well. They are optional when you declare only one parameter name:

arr => {...} // this is fine

arr, number => {...} // this will not work

(arr, number) => {...} // but this will!

You should be aware that the this keyword behaves differently when using arrow functions. It doesn’t have it’s own this or arguments binding. You also can not use it as a constructor, which means this won’t work:

But this will:

If you don’t know much about arrow functions I really recommend reading about them.

forEach, for…of

In the real world I wouldn’t rewrite our for loops in any way, they work just fine. But still, we can definitely do that. Let’s look at what we can do with our first loop.

forEach

Currently looks like this:

for (let i = 0; i < arr.length; i++) {…}

Rewrite it to:

arr.forEach((value, index) => {…})

As you can probably tell forEach executes a function for each and every array item. In the first callback argument we get the array value and in the second we get the index. This isn’t really ideal in our scenario, because we’re not really that interested in the value itself, but more in the index. Let’s look at an example with for…of

More info on forEach.

for…of

Again, our current first loop implementation looks like this:

for (let i = 0; i < arr.length; i++) {…}

With for…of :

for (let i of arr.keys()) {…}

But why do we have arr.keys() ? Well, because for…of iterates over so called iterable objects. If you’re like me you don’t really know for sure what an iterable object is, but in reality the concept itself is not that difficult. Iterable objects are just JavaScript objects that define their iteration behavior with the for...of loop, basically what values are looped over. Some built-in types are Array, String, Map, etc.

When we iterate over an Array (and you can try it out yourself) we only get the array value.

Unfortunately, that’s not what we’re interested in, we want to have the index of the array. For that we can use built-in method called keys() . The keys() method returns a new Array Iterator object that contains the keys for each index in the array. Now we can loop through the array and get the piece that we’re interested in:

Great! It’s really not the best use case, but the concept of the for...of loop is really powerful and you can do a lot of cool things with it.

More info on for…of loop.

Note: for…of loops cousin for…in is not included, because it’s built for iterating over object properties and is not recommended in use with arrays.

Destructuring assignment

Uhhh, that sounds really difficult. And you’re writing about it at the end of the article? When I’m already tired from all of the const and let and var and whatever... But bear with me, it’s not that difficult. It’s just syntactic sugar to unpack values from arrays, or properties from objects, into distinct values. Let’s take a look at a simple example for destructuring:

const arr = [10, 20]

const [a, b] = arr

This is really cool. We can unpack our array values into distinct variables. With destructuring assignment we can do the following:

const [a, b] = [30, 40]

This comes in handy for swapping array values. In ES5 world you need to create a temp variable in order to not lose information on the array element that you’re swapping. Let’s take a closer look.

const arr = [10, 20]

arr[0] = arr[1] // This doesn't work, now both of our values are 20

arr[1] = arr[0] // Will also become 20 :(

For that you need to have a temp variable which saves the previous information and that’s what we’re doing in our example. But with the help of destructuring assignment we can refactor it to:

[arr[i], arr[minimumIndex]] = [arr[minimumIndex], arr[i]]

We’re just swapping the values around really elegantly. If this doesn’t makes sense try looking at our previous example again at the top when we assign const [a, b] = [30, 40]

Summary

With all of that being said our end result looks like this:

I hope that you’ve learnt some new concepts or syntax along the way.

Thanks for reading.