Arrow Functions in JavaScript

Arrow functions were introduced in ES6 to work around several common gotchas with conventional functions. However, you still need to learn when to use conventional functions versus when to use arrow functions, because there are situations where using an arrow function is the wrong choice.

Syntax

When you see => , you're looking at an arrow function. There are two ways to declare an arrow function:

Without curly braces {} . With this syntax, the arrow function has an implicit return. For example, the below arrow function returns 42, even though there's no return .

const getAnswer = () => 42 ; getAnswer();

With curly braces {} . With this syntax, the arrow function does not have an implicit return .

const getAnswer = () => { return 42 ; }; getAnswer();

Returning an object literal from an arrow function is tricky:

const getObj = () => { answer : 42 }; const getObj = () => ({ answer : 42 }); getObj();

Without curly braces, you can only put one expression to the right of the arrow => . Intuitively, this means you can only use the no curly brace syntax for "one-liners". You can use the ternary operator ? , && , and || . But you cannot use if statements or semicolons.

let answer = 42 ; const getAnswer = () => answer !== null && answer !== undefined ? answer : 0 ; getAnswer();

Parameters

Like normal functions, arrow functions can take zero or more parameters. You must put the parameter names in parentheses (param1, param2, param3) => {} unless your arrow function takes exactly one parameter.

const getAnswer = () => 42 ; let noop = v => v; noop = ( v ) => v; const add = ( a, b ) => a + b;

Why Arrow Functions?

Arrow functions have two major advantages:

Implicit return for one-line functions means more concise code Lexical this . this in the arrow function is the same as this outside the arrow function.

For example, suppose you try to call setTimeout() in a class method. If you use a normal function as opposed to an arrow function, this will not be an instance of MyClass .

class MyClass { constructor (message) { this .message = message; } print() { setTimeout( function ( ) { this .message; }, 100 ); } } const obj = new MyClass( 'Hello, World' ); obj.message; obj.print();

With an arrow function, this will be an instance of MyClass .

class MyClass { constructor (message) { this .message = message; } print() { setTimeout( () => { this .message; }, 100 ); } } const obj = new MyClass( 'Hello, World' ); obj.message; obj.print();

Why Not Arrow Functions?

Arrow functions are excellent, and often it doesn't matter whether you use an arrow function or normal function. But when you use a framework that depends on this , you should not use arrow functions.

For example, suppose you declare a Vue method using an arrow function. You won't be able to access the Vue instance's name property because Vue won't be able to set this .

const Vue = require ( 'vue' ); const app = new Vue({ data : () => ({ name : '' }), methods: { setName : newName => this .name = newName }, template : ` <div> <h1>{{name}}</h1> <button v-on:click="setName('Hello')"></button> </div> ` });

Another common case is Mocha timeouts. You can use arrow functions for Mocha tests, but then you can't set the test timeout.

describe( 'MyFunction' , () => { it( 'works' , () => { this .timeout( 500 ); }); });

In general, you should not pass arrow functions to a framework unless you do not intend to use the this keyword. For example, don't use arrow functions for Vue methods, Mocha tests, React class methods, or Mongoose model methods. You may use arrow functions inside a Vue method or a Mocha test, but the top level function that you give to Vue or Mocha should not be an arrow function.

More Fundamentals Tutorials