ES-6 Arrow functions

Abhishek Yadav

Apr-2018

ES-6 Arrow functions


// Traditional function -

var foo = function (x) {
    return x*2;
}


// Equivalent arrow function

var foo = x => x * 2;

ES-6 Arrow functions

  • Skip the function keyword
  • Use => after parenthesis
  • Braces and return keyword are optional for one line expressions as return values
  • Parenthesis around arguments optional when there is a single argument

 

Syntax

ES-6 Arrow functions


// Traditional function -

var foo = function (x) {
    return x*2;
}


// Equivalent arrow functions

var foo1 = (x) => { return x * 2 };
var foo2 = (x) => x * 2;
var foo3 = x => x * 2;

ES-6 Arrow functions

  • Shorter function expressions
  • Non binding of this

Goals

ES-6 Arrow functions

Non binding of this

  • Binding rules for this have been a source of confusion
  • The value of this changes (is reassigned) within a function.
  • The rules governing binding of this are not straightforward. Sometimes it gets bind-ed to the global object unexpectedly.

ES-6 Arrow functions

Non binding of this

// Traditional function -

var obj = {
  x: 99,

  method1: function(){
    console.log(this.x); // 99

    setTimeout(function(){ // *this* changes here
      console.log(this.x); // undefined
    }, 1000);
  }
}

ES-6 Arrow functions

Non binding of this - using arrow function

// 'that' hack -

var obj = {
  x: 99,

  method1: function(){
    console.log(this.x); // 99

    setTimeout(() => {
      console.log(that.x); // 99
    }, 1000);
  }
}

ES-6 Arrow functions

Non binding of this - using arrow function

  • Arrow function is able to retain the expected value of this
  • That is because an arrow function does not try to define its own this. It retains the value from enclosing context

ES-6 Arrow functions

Terse code

list = [
 { type: 'x', score: 99 },
 { type: 'x', score: 49 },
 { type: 'y', score: 88 },
 { type: 'y', score: 57 }
]

// totalScoreTypeX = 
list
  .filter(function(item){
    return item.type === 'x';
  })
  .map(function(item){
    return item.score;
  })
  .reduce(function(acc, score){
    return acc + score;
  })
list = [
 { type: 'x', score: 99 },
 { type: 'x', score: 49 },
 { type: 'y', score: 88 },
 { type: 'y', score: 57 }
]

// totalScoreTypeX = 
list
  .filter(item => item.type === 'x' )
  .map(item => item.score )
  .reduce((acc, score) => acc + score)

ES-6 Arrow functions

Restrictions

// 1. Can't have name

// 2. Doesn't have arguments object

let foo = () => arguments // Error

ES-6 Arrow functions

Restrictions

// 3. Cant be used as constructor

const MyClass = () => {}
let obj = new MyClass() // Error

ES-6 Arrow functions

Restrictions

// 4. Doesn't have prototype property

let foo = () => {}
foo.prototype     // undefined

ES-6 Arrow functions

Restrictions

// 5. Cant be used as generator function

let genFoo = () => {
  yield 123      // Error
}

ES-6 Arrow functions

Restrictions

// 6. Can't be used as object method

let obj = {
  x: 99,

  method1: () => {
    console.log(this.x); // undefined. Not 99
  }
}

ES-6 Arrow functions

Restrictions (more)

  • call() and apply() can get only parameters. Object argument (first one) is ignored
  • Object.defineProperty doesn't work correct with arrow function argument
  • Strict mode rules are ignored
  • Line break not allowed between parenthesis and the arrow.

ES-6 Arrow functions

Caveats

// Returning object literals in 
// concise syntax (one liners) needs caution

let foo = () => { a: 1 }  // Bug. Doesn't return object. 
                          // Doesn't fail
                          // Assigns a label actually

let foo = () => ({ a: 1 })  // function returns object

ES-6 Arrow functions

Caveats

// Precedence is not same as a traditional function

let func;

func = func || function(){}  // ok
func = func || () => {}      // syntax error
                             // precedence rules problem
func = func || (() => {})    // ok

ES-6 Arrow functions

Browser support

  • All but IE-11, Opera Mini
  • Supported on Edge mobile, most Android/IOS browsers
  • Supported on Node.js

 

ES-6 Arrow functions

Trivia - Other arrows in JS

<-- // Comment

--> // Comment and 'goes-to'

<= // The less-or-equal-to operator

ES-6 Arrow functions

Trivia - other arrows <--

<script language="javascript">
<!--
  console.log(document.body)
// -->
</script>
// <-- is a single line comment in JS

// The above will be treated as 
// HTML comment in a JS-disabled browser

// Otherwise, its valid Javascript
// surrounded by comment lines

// This too was standardized in ES6

ES-6 Arrow functions

Trivia - other arrows -->

// --> is also a single line comment in JS

// Everything after the arrow is treated as
// a comment

// And in HTML, 
// everything *before* is a comment 

// Also, 
// it should appear at the beginning of a line.

ES-6 Arrow functions

Trivia - other arrows -->

// --> is also works as the "goes-to" operator 

while (n --> 0) {
  console.log(n);
}


// n goes-to 0
// Is actually just decrement and compare
// and not a special operator

(n--) > 0
(n=n-1) > 0

ES-6 Arrow functions

References

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
  • https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/

ES-6 Arrow functions

By Abhishek Yadav

ES-6 Arrow functions

  • 937