Arrow functions in ECMAScript 6 (ES6)

Hi All,

You will find some of the new features introduce in ES 6 in my previous post. Now let’s get more details on Arrow functions in ECMAScript 6.

The ECMAScript 6 arrow function syntax is a shorthand for the ECMAScript 5 function syntax. It supports both block and expression bodies. The value of this inside the function is not altered: it is the same as the value of this outside the function. No more var self = this to keep track of the current scope.

Here’s how the syntax looks like if we have a single argument and just want to return the results for an expression.

[1, 2, 3].map(num => num * 2) // <- [2, 4, 6]

/* ES5 equivalent */
[1, 2, 3].map(function (num) { return num * 2 }) // <- [2, 4, 6]

If we need to declare more arguments (or no arguments), we’ll have to use parenthesis.

[1, 2, 3, 4].map((num, index) => num * 2 + index) // <- [2, 5, 8, 11]

You might want to have some other statements and not just an expression to return. In this case you’ll have to use bracket notation.

[1, 2, 3, 4].map(num => {
  var multiplier = 2 + num
  return num * multiplier
}) // <- [3, 8, 15, 24]

If we need to return an object literal, we’ll have to wrap the expression in parenthesis. That way the object literal won’t be interpreted as a statement block (which would result in a silent error or worse, a syntax error because number: n isn’t a valid expression in the example below. The first example interprets number as a label and then figures out we have an n expression. Since we’re in a block and not returning anything, the mapped values will be undefined. In the second case, after the label and the n expression, , something: ‘else’ makes no sense to the compiler, and a SyntaxError is thrown.

[1, 2, 3].map(n => { number: n })
// [undefined, undefined, undefined]

[1, 2, 3].map(n => { number: n, something: 'else' })
// <- SyntaxError

[1, 2, 3].map(n => ({ number: n }))
// <- [{ number: 1 }, { number: 2 }, { number: 3 }]

[1, 2, 3].map(n => ({ number: n, something: 'else' }))
/* <- [
  { number: 1, something: 'else' },
  { number: 2, something: 'else' },
  { number: 3, something: 'else' }]
*/

A cool aspect of arrow functions in ES6 is that they’re bound to their lexical scope.

function Timer () {
  this.seconds = 0
  setInterval(() => this.seconds++, 1000)
}
var timer = new Timer()
setTimeout(() => console.log(timer.seconds), 3100)
// <- 3

Keep in mind that the lexical this binding in ES6 arrow functions means that .call and .apply won’t be able to change the context. That means invoking an arrow function through the call() or apply() methods can only pass in arguments, but has no effect on this:

var adder = {
  base : 1,
    
  add : function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };
            
    return f.call(b, a);
  }
};

console.log(adder.add(1));         // This would log to 2
console.log(adder.addThruCall(1)); // This would log to 2 still

I think arrow functions are particularly useful in most functional programming situations such as when using .map, .filter, or .reduce on collections. Similarly, arrow functions will be really useful in asynchronous flows since those typically have a bunch of callbacks that just do argument balancing, a situation where arrow functions really shine. Please share your thoughts on arrow functions in comments.

Advertisements

What’s new in ECMAScript 6 (ES6)

Hi All,

In front-end development, most of you might heard about ECMAScript 6 (ES 6) – next version of JavaScript.  ECMAScript 6 has some great new features. Here I have list out some of the new features in ECMAScript.

Note – Some of the modern browsers are supporting some of ES 6 features. If you still want to use ES 6 features for older browsers then you need compiler which compiles the ES 6 code such as Babeltraceur.

Continue reading