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
- 1,107