When and why you should use ES6 arrow functions/tradional function — and when you shouldn’t
In this article, you'll learn about JavaScript arrow functions and regular functions, what the major difference between them is, and when we should use one over the other. You'll see lots of examples that illustrate how they work.
Table of contents
- Syntax difference
- Syntaxically anonymous
- When you should use arrow function
- When you should not use arrow function
1. Syntax Diffrence
Functions are like recipes where you store useful instructions to accomplish something you need to happen in your program, like performing an action or returning a value. By calling your function, you execute the steps included in your recipe. You can do so every time you call that function without needing to rewrite the recipe again and again.
It is very important to understand how arrow function works differently compared to regular ES5 functions.
a) Regular function
Here we can see the way of deceleration and calling a regular function in JavaScript.
// function declaration
function Subtract(a,b){
return a-b;
}
// call the function
let sum = Subtract(9,3);
b) Arrow function
Now, here is the same function expressed as an arrow function.
// By Arrow function
let Subtract = (a,b) => a-b
// call function
let ans = subtract(9,3)
It’s much shorter! We are able to omit the curly braces and the return statement due to implicit returns (but only if there is no block — more on this below).
Variations
One thing you will find fascinating when you notice the variety of syntax availible in arrow functions.
1. No parameters
If there are no parameters, you can place an empty parentheses.
() => 42
2. Single parameter
With these function, parentheses are optional
x => 42 || (x) => 42
3.Multiple parameters
Parentheses are required for these functions
(x,y) => x = y
4.Statements
With arrow functions, it is important to remember that statements need to have curly braces. Once the curly braces are present, you always need to write return as well.
Here is an example of arrow function used with if statement:
var feedTheCat = (cat) => {
if (cat === 'hungry') {
return 'Feed the cat';
} else {
return 'Do not feed the cat';
}
}
5. Block body
If your function is in a block , you must use the explicit return
statement
var addValues = (x, y) => {
return x + y
}
6. Object literals
If you are returning an object literal, it need to be wrpped in parentheses. This also makes the interpreter clear to evaluate what is inside the parentheses.
x =>({ y: x })
Syntactically anonymous
It is important to note that arrow functions are anonymous, which means that they are not named. This will create some issues listed below.
a) Harder to debug
When you get an error, you will not be able to trace the name of the function or the exact line number where it occurred.
b) No self-Referencing
If your function needs to have a self-reference at any point (e.g. recursion, an event handler that needs to unbind), it will not work.
When you shlould use Arrow functions.
1. Lexical this
The keyword this
is often considered a tricky topic in javascript. This article will help you to understand how this
works.
Arrow function have lexical this
, meaning the value of this will be from the parent scope in which the arrow function is present.
Now, we will se the demonstartion of how traditional function and arrow function handels this
.
const printNumbers = {
phrase: 'The current value is:',
numbers: [1, 2, 3, 4],
loop() {
this.numbers.forEach(function (number) {
console.log(this.phrase, number)
})
},
}
In the following code snippet printNumber
object , there are two properties: phrase
and numbers
. There is also a method on the object, loop, which should print the phrase
string and the current value in numbers
Now, You yes! you might expect the loop
function to print the string and current number in the loop on each iteraton. However, in the result of running the function the phrase
is actually undefined
. Shocked?
This will give the following:
Output undefined 1 undefined 2 undefined 3 undefined 4```
As this shows, this.phrase
is undefined, indicating that this
within the anonymous function passed into the forEach
method does not refer to the printNumbers object. This is because a traditional function will not determine its this value from the scope of the environment, which is the printNumbers object.
To solve this problem , you would have had to use the bind
method, which explicitly sets this
Use bind
ti fix the function
const printNumbers = {
phrase: 'The current value is:',
numbers: [1, 2, 3, 4],
loop() {
// Bind the `this` from printNumbers to the inner forEach function
this.numbers.forEach(
function (number) {
console.log(this.phrase, number)
}.bind(this),
)
},
}
printNumbers.loop()
This will give the expected output
Output
The current value is: 1
The current value is: 2
The current value is: 3
The current value is: 4
Arrow function provides a more easier and direct way of dealing with this. Since their this
value is determined based on the lexical scope, the inner function called in forEach
can now access the properties of the outer printNumbers
object, as demonstrated:
const printNumbers = {
phrase: 'The current value is:',
numbers: [1, 2, 3, 4],
loop() {
this.numbers.forEach((number) => {
console.log(this.phrase, number)
})
},
}
printNumbers.loop()
This will give the expected result:
Output
The current value is: 1
The current value is: 2
The current value is: 3
The current value is: 4
These examples establish that using arrow functions in built-in array methods like forEach
, map
, filter
, and reduce
can be more intuitive and easier to read, making this strategy more likely to fulfill expectations.
When you shlould not use Arrow functions.
1. Object Methods
While arrow functions are excellent as parameter functions passed into array methods, they are not effective as object methods because of the way they use lexical scoping for this. Using the same example as before, take the loop method and turn it into an arrow function to discover how it will execute:
const printNumbers = {
phrase: 'The current value is:',
numbers: [1, 2, 3, 4],
loop: () => {
this.numbers.forEach((number) => {
console.log(this.phrase, number)
})
},
}
In this case of an object method, this should refer to properties and methods of the printNumbers object. However, since an object does not create a new lexical scope, an arrow function will look beyond the object for the value of this and beyond this arrow function will lokk fro this in outer space.
2. Prototype methods
Prototype is a property ,which is what javascript uses as a blueprint for cloning.
To illustrate this,create a function and log the automatically assigned prototype property:
function myFunction() {
this.value = 5
}
// Log the prototype property of myFunction
console.log(myFunction.prototype)
This will print the output to the console:
Output
{constructor: ƒ}
This show that in the prototype property there is an object with a constructor this also allows to use new keyword to create an instance of function.
In contrast, arrow functions do not have a prototype property. Create a new arrow function and try to log its prototype:
```const myArrowFunction = () => {}
// Attempt to log the prototype property of myArrowFunction console.log(myArrowFunction.prototype)```
This will give the following :
Output
undefined
As a result of the missing prototype property, the new keyword is not available and you cannot construct an instance from the arrow function.
3. Arguments object
Arrow functions don’t have the arguments object. Therefore, if you have a function that uses arguments object, you cannot use the arrow function.
For example, the following concat() function won’t work:
const concat = (separator) => {
let args = Array.prototype.slice.call(arguments, 1);
return args.join(separator);
}
Instead, you use a regular function like this:
function concat(separator) {
let args = Array.prototype.slice.call(arguments, 1);
return args.join(separator);
}
Summary
An arrow function doesn’t have its own this value. Instead, it uses the this value of the enclosing lexical scope. An arrow function also doesn’t have the arguments object.
Avoid using the arrow function for event handlers, object methods, prototype methods, and functions that use the arguments object.