What Changed with Arrow Functions

With the introduction of the arrow functions in JavaScript, everyone is happy. Well, why shouldn’t we be? It clears one of the biggest confusion in JavaScript. The confusion with the scope inside an event handler or a callback function, or to be precise scope within a scope.

When ES6 was introduced, it removed the traditional function level scope and replaced it with the block level scope using let and const [more about this in a later post]. Now we don’t need to worry about binding or referencing the scope in our callback functions.

In ES5, we have to write:

var _this = this;
el.addEventListener ("click", function (e) {
    // do something with _this
});

In ES6, we can write:

el.addEventListener ("click", (e) => {
    // do something with this
});

It might seem a small thing here, but the fat arrows have made understanding the scope easy, especially for people who have come from the C/C++ background. The syntax is neat and short, and as I said, we don’t have to worry about the scope anymore. But everything comes with a tradeoff.

Last night I was working on something and I had to reorder the elements of an array. Given two indices, i.e. source and destination, the elements should be swapped. We all must have done this program/script at least once, swapping two numbers. But since I had to do for an array, I thought let’s create a function on array’s prototype, so that I would be able to use it like any other functions of the array (like map, filter, reduce, etc). Since I was working in ES6, I used the fat arrow for the declaration.

Array.prototype.swap = (sourceIndex, destIndex) => {
  let temp = this[sourceIndex];
  this[sourceIndex] = this[destIndex];
  this[destIndex] = temp;
  return this;
}

Hang on! What’s this here? As expected my code didn’t work, and I had to switch back to the ES5 syntax here to make it work.

Array.prototype.swap = function(sourceIndex, destIndex) {
  let temp = this[sourceIndex];
  this[sourceIndex] = this[destIndex];
  this[destIndex] = temp;
  return this;
}

Another thing which has been omitted from arrow functions and which is noticeable is, the default arguments passed to the functions. In ES5, we have an array like object, which is called arguments. All functions have it. A use case of using arguments object is writing a function, which returns the sum of all arguments passed to it, where the number of arguments is not known.

var adder = function () {
  var sum = 0;
  for (var i = 0; i < arguments.length; i++) {
    sum += argumets[i];
  }
  return sum;
}

We do not have arguments object in ES6, but we do have spread operator. We can create the same function like this,

const adder = (...options) => {
  var sum = 0;
  for (var i = 0; i < options.length; i++) {
    sum += options[i];
  }
  return sum;
}

PS: These examples are only for illustration purpose, same functionalities could be achieved using different method/logic as well.