DEV Community

loading...
Cover image for Arrow Functions in JavaScript, How is it different?

Arrow Functions in JavaScript, How is it different?

Tahir Ahmed Tapadhar
Tech Enthusiast, C#, Javascript, .NET , Cloud, Life-long Learner, Polymath & an aspiring polyglot
・5 min read

JavaScript has seen a lot of changes in the past few years making it robust, elegant & the primary choice language of the web. Ever since ES6 was released, JavaScript has become a different ballgame altogether with various drastic changes adding to it's elegance. With each successive ES release, it brought a lot of cool stuff to the table. One such major breakthrough came with the release of ES6 which introduced features like the let & const keywords, template literals, the class keyword, modules, destructuring and a lot more. Among these hallmark was the 'Arrow Functions'.

Ever since it's inception, it has been widely acclaimed & adopted by the JS developers/community. It is been widely used in libraries & big frameworks like Angular, React, Vue, etc. It has completely changed the way we look & write functions in JS making it short and concise. Before diving in, let's talk briefly about traditional ways of writing functions in JavaScript.

Functions in JS:

There are a few different ways to define a function in JavaScript.

  • Function declaration:

A function declaration defines a named function. To create a function declaration you use the function keyword followed by the name of the function.

// function declaration
function add(a, b){
   return a + b;
}

console.log(add(1,2)); //3
Enter fullscreen mode Exit fullscreen mode
  • Function expression:

A function expression is very similar to and has almost the same syntax as a function declaration. The main difference between a function expression and a function declaration is the function name, which can be omitted in function expressions to create anonymous functions. In simple words, a function expression can be defined as an anonymous function assigned to a variable.

// function expression
var add = function (a, b){
   return a + b;
}

console.log(add(1,2)); //3
Enter fullscreen mode Exit fullscreen mode
  • Function() Constructor:

The function statement is not the only way to define a new function, you can define your function dynamically using Function() constructor along with the new operator. This is how we can use the Function() constructor to create functions.

var add = new Function('a','b','return a+b;');

console.log(add(1,2)); //3
Enter fullscreen mode Exit fullscreen mode

However creating functions using this method is not recommended. Calling the constructor directly can create functions dynamically but suffers from security and similar performance issues.

Apart from the above mentioned methods, there is a new way to define functions in JavaScript post the release of ES6 and that is the Arrow Function.

Arrow Functions:

The Arrow function is the latest way to define a function in JS. It is a shorter syntax for writing function expressions. An arrow function is a cleaner, concise & a compact alternative to a traditional function expression, but is limited and can't be used in all situations. Here is how we write the above function using the Arrow function syntax.

// arrow function
var add = (a,b) => {
   return a + b;
}
Enter fullscreen mode Exit fullscreen mode

In an arrow function , we don't require a function keyword. Instead we use a fat arrow (=>) between the parameters and the body of the function. The above arrow function can also be compacted further. If the body of our function includes only a single line, we can write the function like this.

var add = (a,b) => { return a + b; } 
Enter fullscreen mode Exit fullscreen mode

Also, if there is a single line of code in the function body & returns a value, we can eliminate both the return keyword and the {} braces completely like this.

var add = (a,b) => a + b;  
Enter fullscreen mode Exit fullscreen mode

Here are the 2 methods: The latter arrow function that we have is exactly equivalent to the former function expression shown above.

// function expression
var add = function (a, b){
   return a + b;
}

// arrow function
var add = (a,b) => a + b;  
Enter fullscreen mode Exit fullscreen mode

You can see, this syntax is cleaner & more compact and makes you write less lines of code.😃

Note:

If the arrow function has a single parameter, we can skip writing the parenthesis () i.e. we need not require the parenthesis () for enclosing the single parameter. But if the function has more than one parameter, parenthesis is required.

var greet = name => console.log('Hi' + name);

greet('Tahir'); // 'Hi Tahir'
Enter fullscreen mode Exit fullscreen mode

How are Arrow functions different?

The obvious question you must be asking yourself is what was the need for introducing arrow functions and why should I use it. One good reason would be, that it would make your code look more readable & smaller by eliminating good amount of lines.
Further more, I will replace all my existing functions that I have defined using function declaration/expression with Arrow functions and my code will work the same as before. Big deal? The answer to that is NO!!. Don't do that.

Even though at first it might look like there is just a syntax difference between them, but that is not true. There are quite subtle differences between the Arrow functions & the traditional methods. Let's discuss what are they.

  • 'args' object:

Arrow functions don't have access to arguments object. Let's understand this with an example.

// function expression
var add= function(a,b) {
   console.log(arguments[0]); // 1
   console.log(arguments[1]); // 2
   return a + b;
}

add(1,2); // 3

// arrow function
var add = (a,b) => console.log(arguments[0]);

add(1,2); // arguments is not defined
Enter fullscreen mode Exit fullscreen mode
  • Arrow functions don't have their own 'this':

The behavior of this inside of an arrow function differs considerably from the regular function’s this behavior. It does not have its own bindings to this and should not be used as methods.

var person = {
  age: 15,
  print() {
    console.log(this.age);
  }
};

console.log(person.print()); // 15
Enter fullscreen mode Exit fullscreen mode
var person = {
  age: 15,
  print: () => {
    console.log(this.age);
  }
};

console.log(person.print()); // undefined
Enter fullscreen mode Exit fullscreen mode

Traditional functions default this to the window scope. Arrow functions do not default this to the window scope, rather they execute in the scope they are created.

var person = {
   eat() {
      setTimeout(function(){
         console.log('this', this);
      }, 1000);
   }
};

person.eat(); // {Window Object}
Enter fullscreen mode Exit fullscreen mode

Upon invoking person.eat(), this prints a window object. The reason this happened because here, the callback function inside setTimeout() is not part of any object. It's a standalone function. When we call a function as a standalone function outside of an object, by default this points to window object.

var person = {
   eat() {
      setTimeout(() => {
         console.log('this', this);
      }, 1000);
   }
};

person.eat(); // {person Object}
Enter fullscreen mode Exit fullscreen mode

This can be resolved using an Arrow function because they don't rebind this. In other words, if we change the callback to an arrow function, it will inherit the this keyword. In the callback function, because we have used the arrow function syntax, the value of this is not reset. Instead it inherits the value of this in the context in which this code is defined.

  • Arrow functions cannot be used as a constructor:

If you are aware of constructor functions in JavaScript, then you should know that a regular function can easily construct objects. For example, the Person() function creates instance of a person class

function Person(name) {
  this.name = name;
}

var person1 = new Person('Tahir');
person1 instanceof Person; // true
Enter fullscreen mode Exit fullscreen mode

The arrow function resolves this lexically. In another words, the arrow function doesn’t define its own execution context. A consequence of this resolved lexically is that an arrow function cannot be used as a constructor. If you try to invoke an arrow function prefixed with new keyword, JavaScript throws an error:

var Person = (name) => {
  this.name = name;
}

var person1 = new Person('Tahir'); // TypeError: Person is not a constructor
Enter fullscreen mode Exit fullscreen mode

That's all there is to Arrow Functions. In a nutshell, we simply cannot interchangeably use Arrow functions over Function expressions or vice versa. The right way to go would fully depend upon the requirement of how you want to build things as per need. Hope this was helpful. Happy Learning🙂🙂..

Discussion (0)