Monday, March 21, 2016

Arrow Functions

I love the new arrow function in EcmaScript 6.  I use it for everything, pretty much all the time :)

Quick Rundown

Basic Form

var add = (numberOne, numberTwo) => {
  return numberOne + numberTwo;
add(1, 2);
//returns 3

Here I'm creating a function named add that takes two parameters, numberOne and numberTwo.  This function will return the two numbers added together.  When the body of the function is a single expression, we can write this even more concisely.

var add = (numberOne, numberTwo) => numberOne + numberTwo;

At first glance, this looks just like a different syntax for creating a function.  But there's more to it than that.  Inside of the arrow function, there is no new 'this' pointer defined.

Let's look at an example (taken from MSDN:

function Person() {
  var self = this; // Some choose `that` instead of `self`.
                   // Choose one and be consistent.
  self.age = 0;

  setInterval(function growUp() {
    // The callback refers to the `self` variable of which
    // the value is the expected object.
  }, 1000);

Notice the strange self variable we had to create in order to access age.  This is because the function growUp gets a brand new 'this' pointer that is quite different than the 'this' pointer inside of Person.  That means that when growUp is called, calling this.age will not work, because there is no 'age' variable inside of the growUp function.  The new fat arrow fixes this:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);

Notice that 'this' can correctly find and use the age variable.  This is very nice and just feels much better overall.


1.  Returning an object literal needs to be wrapped in parens.

const gimmeFoo = () => {  foo: 1  };
//will not work!  calling gimmeFoo() returns undefined

instead do this:

const gimmeFoo = () => ({  foo: 1  }); 

2.  You also cannot override the 'this' inside of an arrow function.  That means that bind is useless here, so don't try it.  Same thing for call and apply.  You can still pass in arguments, but you cannot override 'this'.

3.  You also don't have access to the 'arguments' variable, but a good workaround is to use rest parameters (, which we won't cover here.

var f = (...args) => args[0];

4.  Even if you don't have arguments, you still need the parens:

const gimmeHi = () => 'hi';

but you can also do this:

const gimmeHi = _ => 'hi';
That's pretty much it! Go forth and start using it :)

No comments: