Justin Chmura
Blarg

3 Gotchas to Using ES6 Arrow Functions

By on

With the recent release of new JavaScript spec, ES6 arrow functions will start to show up more and more in JavaScript code. If you aren’t familiar, arrow functions are just a way to define a function without needing the function keyword.

Although it may just look like syntactic sugar, similar to how the new class keyword is, it does cause the function to behave slightly different. If you aren’t aware of it, those differences could cause some debugging headaches.

Here’s 3 gotchas that you should be on the lookout for.

#1: Lexical ‘this’ Binding

What does that mean? For typical JavaScript functions, the value of this is defined as an instance of itself as if used as a constructor.

function Person(name) {
  this.name = name; // 'this' is an instance of Person
}

var p = new Person('Justin');

Arrow functions do not do that. this is inherited from the scope of which the arrow function is defined. With that rule in mind, it is also good to know that arrow functions are not ‘newable’. They cannot be used as constructors and will throw an error if used in that way.

You might ask, why the change in rules? Well this is actually extremely useful when using them as callbacks. How many times have you done this hack:

function Person() {
  var self = this; // <-- hack
  self.name = '';
  $.get('/api/person/1', function (name) {
    self.name = name;
  });
}

With arrow functions, that hack is no longer needed:

function Person() {
  this.name = '';
  $.get('/api/person/1', (name) => {
    this.name = name;
  });
}

Another thing to keep in mind as well, is arguments performs the same way in that it inherits its values from the calling scope. Arrow functions do not have an arguments object.

#2: ‘this’ Cannot Be Changed

Relating to the first point, this cannot be changed inside the function. If you try and run this code:

var test = () => {
  this = { prop: 1 };
  console.log(this.prop);
};

test();

There’s an error that pops up in the console. This is to retain the rule in the first point of the function using its scope to define what this is.

Even though arrow functions safe guard against that with an error, that’s not something that’s encouraged due to it causing debugging headaches.

#3: Implied Returns

This is a small gotcha, but if you’re not aware of it, can be a little weird. Since curly braces are optional for arrow functions, they can be left off to create a super simple function. In those types of definitions, the result of the expression is always returned.

var first = (x) => x + 1;
var second = (x) => { return x + 1; };

console.log(first(1));
console.log(second(1));

Both of those functions do the same thing.

This is actually less of a gotcha, than a neat feature because it allows you to write some extremely functional looking code without the extra keyword fluff.

Go Forth and Conquer

Arrow functions are a neat addition to the JavaScript language and I encourage you to start getting familiar with them. They make creating simple callbacks elegant and allow some better structure than having to deal with regular function scope.