Arrow functions are a new way of writing a traditional function. This way the function is shorter and quicker to write. Arrow functions were introduced in ES6.
Let’s see how we write functions in a traditional way:
Now let’s transform this traditional function into an arrow function:
So what do you notice? The function
keyword is removed and an arrow =>
is added for the expression.
We can simplify the above example a little more by removing the return
statement:
Do you notice how the curly braces and return
is gone? Remember, that you can only do this if the first line of the
function body is a return
statement.
In the above example, we have two parameters a
and b
. But what if there was only one parameter? Then we can make it
even shorter:
We have removed the parenthesis as well because there was only one parameter salary
. Remember that we can’t do this
if there is no parameter or parameters are more than one.
Let’s do the sorting of numbers with both traditional and arrow functions:
Let’s do the same example with the arrow function:
That’s short and simple. ❤
You might want to watch out while returning an object in an arrow function. You can’t do it like this:
The correct way using ( )
:
That’s the cosmetic difference between our good old traditional function declaration and the new arrow function. But there is more to it than these fancy changes. ⚡
Let’s talk about this
Traditional functions have their own this
binding while arrow functions don’t. Arrow functions can only access
this
from their parent scope. So if you use this
in an arrow function then it will refer to the object of that
arrow function’s parent.
Let’s understand this by an example:
In the above example, we have set the age to 130
on window
object. Now inside the EdwardCullen
we have
setTimeout
declared in a traditional way by using function()
.
Now if you try to print this.age
in setTimeout
, you will get 130
which was declared directly as window
object.
Do you know why? Because setTimeout
does not have its own this.age
declared inside it. So it fetches it by
default from the window
object. It doesn’t care about this.age
declared in the parent scope.
Let’s see the above example using the arrow function:
Now this.age
inside setTimeout
prints 17
instead of printing the age from window
scope. Our arrow
function setTimeout
tries to find this
in the immediate lexical scope of the parent rather than looking
in the window
scope.
This eliminates the confusion and issues with traditional function declaration where this
might work in an
unexpected and confusing way.
Let’s take another example to understand this:
The above example prints undefined
because this.age
is not defined inside setTimeout
function. Our traditional
function, expects it to be defined in the function itself, if not then it seeks that information in window
object.
Here we don’t have age
in window
object either. So it prints undefined
.
Can we fix this without using an arrow function? Let’s see:
Do you notice let self = this
? This way we can store this
in another variable named self
and then we can use
self.age
inside setTimeout
instead of using this
. Now it prints 120
correctly. This is how we used to solve
this problem before arrow functions.
Well, we have the arrow functions now, so we don’t have to do this little hack anymore:
Here we changed the traditional setTimeout
function to an arrow function and it printed 120
correctly. We didn’t
have to do the self
hack to achieve this. It worked because the arrow function got no binding for this
for itself,
so it tries to find the binding from the parent function which is declared as 120
in age
parameter of realAge
method.
Limitations of Arrow functions
Arrow functions remove the complexity of this
but that comes with some limitations:
1. Shouldn’t be used as methods
It is not recommended to use arrow functions as methods because of the unexpected results. Let’s understand this by an example:
As you can see in the above example, getAge
is using the window object with normal function, so it prints 10
while
the getRealAge
function has no binding and no near lexical scope inside edwardCullen
so it will print undefined
In this, particular case, we should stick with getAge
by using traditional function declaration. Arrow functions are
not a good fit for such cases as evident in the above example.
2. apply
, bind
and call
shouldn’t be used
apply
,bind
, and call
work as expected with traditional functions, because we establish the scope for each of the
methods, but it’s not the case with arrow functions.
Let’s take a look at the traditional way first:
We get the age 77
if we use the traditional function.
We get the age 180
if we use the arrow function. 😁
Now you can see the difference and why it is suggested NOT to use apply
, bind
and call
with arrow functions.
3. Can not be used as constructors
Arrow functions cannot be used as constructors and they don’t have prototype
property as well:
Error:
Undefined:
I hope you learned something today from this article!
Stay awesome and keep rocking! 🌟