Introduction

ES6 introduced arrow functions. In arrow functions, we drop the function keyword.

Pre-ES6 functions declaration and function expression

// function declaration
function add(x , y) {
  return x + y // add and return value to calling function in one line
}
// somewhere else
const sum = add(2, 8)
console.log(sum) // prints 10

// function expression
const multiply = function (x, y) {
  return x * y
}

ES6 Arrow functions

In ES6 arrow functions:

  1. we drop the function keyword
  2. before after the params, we introduce “arrow” symbol => , equal symbol +
  3. function signature takes this form (param1, param2) => { body}
  4. we assign this to a const to make it usable elsewhere in our program. so a complete signature for arrow function becomes:
const arrowFn = (param1,param2) => { 
 // function body
}

Rewriting the above Pre-ES6 function becomes:

// function expression
const add = function (x, y) {
  return x + y
}

// in ES6 arrow functions, becomes:
const add = (x, y) => {
  return x + y
}

// usage
const sum = add(2, 8) // sum now holds value of 10
console.log(sum) // prints 10 to the console

Droping the parentheses and the return keyword altogether.

const add = (x, y) => x + y

Arrow functions and lexical this

In JavaScript this points to the window object of the browser(in the browser).

Checking this object from browser console: a code snippet screenshot

From the above, this === window objects.

Checking the window object from browser console: a code snippet screenshot

In JavaScript, this keyword points to the object in the current execution context. You’d rarely use this unless your code requires an explicit use of this

Say you have a function,

function multipy() {
  console.log(typeof this)
}
multiply() // prints object, when multiply is called, we this will point to the global this, window object in the browser environment

In an object literal:

const hero = {
  name: 'Sasuke',
  printDetails: function() {
    console.log(`hero details, name: ${this.name}`)
  },
  printThis: function() {
    console.log(this) // when called, this will point to hero object, logs hero object, try it out :)
  }
}
hero.printDetails() // prints hero details, name: Sasuke
hero.printThis() 

Arrow function lacks its “own” this. Using the arrow function in object literals causes this to point to the lexical this and not the enclosing object literal.

Observe:

const hero = {
  name: 'Sasuke',
  // change to arrow function
  printDetails: () => {
    console.log(`hero details, name: ${this.name}`) 
  },
  printThis: function() {
    console.log(this) // when called, this will point to hero object, logs the surrounding this, eg window object, try it out :)
  }
}
hero.printDetails() // prints hero details, name: undefined
hero.printThis() // logs refference to the  "surrounding object" 

Summary

Arrow functions introduce a cleaner syntax for writing function expressions. Arrow functions do not replace regular function declaration.

When to use Arrow functions:

  1. In callbacks: items.map((item) => { // do something with item}) is a bit cleaner than items.map(function(item) { // do something with item})
  2. Create functions that are not not hoisted. Function declarations(the pre-ES6 functions) get hoisted and can be called anywhere in the program.

Read more about 👉 for/of