2. Arrow Functions

Arrow functions are a short-hand notation for writing functions in ES6. The arrow function definition consists of a parameter list ( ... ), followed by the => marker and a function body. For single-argument functions, the parentheses may be omitted.

  1. // Classical Function Expression
  2. function addition(a, b) {
  3. return a + b;
  4. };
  5. // Implementation with arrow function
  6. const addition = (a, b) => a + b;
  7. // With single argument, no parentheses required
  8. const add5 = a => 5 + a;

Note that in the above example, the addition arrow function is implemented with “concise body” which does not need an explicit return statement. Note the omitted { } after the =>.

Here is an example with the usual “block body.” Including the curly brace wrappers.

  1. const arr = ['apple', 'banana', 'orange'];
  2. const breakfast = arr.map(fruit => {
  3. return fruit + 's';
  4. });
  5. console.log(breakfast); // ['apples', 'bananas', 'oranges']

Behold! There is more…

Arrow functions don’t just make the code shorter. They are closely related to this binding behavior.

Arrow functions behavior with this keyword varies from that of normal functions. Each function in JavaScript defines its own this context but arrow functions capture the this value of the nearest enclosing context. Check out the following code:

  1. function Person() {
  2. // The Person() constructor defines `this` as an instance of itself.
  3. this.age = 0;
  4. setInterval(function growUp() {
  5. // In non-strict mode, the growUp() function defines `this`
  6. // as the global object, which is different from the `this`
  7. // defined by the Person() constructor.
  8. this.age++;
  9. }, 1000);
  10. }
  11. var p = new Person();

In ECMAScript 3/5, this issue was fixed by assigning the value in this to a variable that could be closed over.

  1. function Person() {
  2. const self = this;
  3. self.age = 0;
  4. setInterval(function growUp() {
  5. // The callback refers to the `self` variable of which
  6. // the value is the expected object.
  7. self.age++;
  8. }, 1000);
  9. }

As mentioned above, arrow functions capture the this value of the nearest enclosing context, so the following code works as expected, even with nested arrow functions.

  1. function Person() {
  2. this.age = 0;
  3. setInterval(() => {
  4. setTimeout(() => {
  5. this.age++; // `this` properly refers to the person object
  6. }, 1000);
  7. }, 1000);
  8. }
  9. let p = new Person();

Read more about ‘Lexical this’ in arrow functions here