Overview Of ES6 Arrow Functions

ES6 Arrow functions

Arrow Functions is undoubtedly one of the most popular features of ES6. They introduced a new way of writing concise functions. They have two major benefits that most people will use them.
First, they provide a shorthand syntax for declaring functions and cutting down the overall amount of code that we need to write for a function. Next, they simplify the behavior of this keyword in JavaScript by keeping its context in the same scope as the function using it.
Let's understand the above-mentioned things in detail.
Let's take a look at a simple function and re-implement it as an arrow function. 
  1. function sayHi(name){      
  2.    return "Hi, "+ name;      
  3. }      
  5. sayHi(Joey);   
Here, we've written a function called sayHi.
When we pass a value like Joey for the name parameter, it will return Hi, Joey.
Let's create a new function using the arrow style called sayHi.
  1. const sayHi = (name) => {      
  2.    return "Hi, "+ name;      
  3. };    
First, we'll have to declare a variable to hold it, we'll use const instead of let since we don't expect that this function will change while it's in scope. Arrow functions are sometimes called fat arrow functions or lambda functions, but the official ES6 term is an arrow function.
You may notice that it doesn't look like we've shortened things much versus a regular function declaration. But if our function is a one-liner then we can omit the curly braces and the return keyword.
  1. const sayHiMiniVersion = name => "Hi, "+ name;      
  2. const timesThree = number => number*3;      
  3. const multiply = (x, y) => x*y;    
A pivotal thing about arrow functions is how they work with the JavaScript keyword.
In traditional-style JavaScript functions, the keyword "this" references depend on how we've called the function. Sometimes keyword "this" references the containing function, sometimes "this" references the global namespace, sometimes "this" references the ajax call, and sometimes "this" references something else altogether. It's difficult to know in advance because it all depends on how the calling code was implemented.
Arrow functions are different because this always refers to the containing code. The fancy term for this is lexical binding.
Let's try to understand with an example 
  1. let Student = function(name, age) {        
  2. this.name = name;        
  3. this.age = age;        
  4. this.detail = function() {        
  6.    // logs Student name and age      
  7.    console.log(this.name + "  "+this.age);        
  9.    setTimeout(function() {        
  10.       // here this!=Student        
  11.       console.log(this.name + " is " + this.age +        
  12.       " years old");        
  13.       }, 4000);       
  14.    }        
  15. }        
  17. let studentJoey = new Student('Joey', 26);        
  18. studentJoey.detail();     
The output would be as below.
Joey 26
undefined is undefined years old
The reason that we get undefined outputs instead of the proper because the setTimeout function() is defined as a normal function which means that its context is set to the global context or in other words, the value of keyword "this" is set to the window object. As every regular, non-arrow function defines its own keyword "this" or context depending on their invocation.
It had returned the correct value if it would have inherited the context from the detail() function which is part of "Student" object. 
Well, that is precisely what arrow functions do. They retain the value of keyword this from their enclosing context. 
  1. let Student = function(name, age) {          
  2. this.name = name;          
  3. this.age = age;          
  4. this.detail = function() {          
  5.    // logs Student  name and age        
  6.    console.log(this.name + " "+this.age);          
  7.    setTimeout(() => {          
  8.       // arrow function to make lexical "this" binding          
  9.       // here this=Student. "this" has been inherited from "this.detail"          
  10.       document.write(this.name + " is " + this.age          
  11.       + " years old");          
  12.       }, 4000);          
  13.     }          
  14. }          
  15. let studentJoey = new Student('Joey', 26);          
  17. studentJoey.detail();     
The output would be,
Joey 26
Joey is 26 years old

One more thing to keep in mind while using ES6 arrow functions

In ES6 there's not a built-in arguments object available inside an arrow function like there is in a regular function. 
  1. const testArguments = function() {      
  2.   console.log(arguments[0] === 1);      
  3.   console.log(arguments[1] === 2);      
  4.   console.log(arguments.length === 3);      
  5. }      
  7. testArguments (1, 2, 3);    


If we need to iterate over the arguments passed to an arrow function we'll have to use an ES6 REST parameter. We'll talk about other ES6 features like rest and spread operators in other articles.