JavaScript: Arrow Functions vs Functions

Are they really the same?

Daniel Afonso
Feb 7 · 5 min read

Hey everyone!

Very often I’ve heard “arrow functions and functions in JavaScript are the same and just have a different syntax”. To clear this up, I’m going to refer to some use cases where they behave differently, including some whys and notes.

this and arguments

this

A function using this

It would be to expect that the output would be helloand hello from this. But instead, the output was the following:

Function using this output

This happens because the value of this is determined accordingly with how that function is called during runtime. So that anonymous function is using the this provided by the setTimeout instead of the one in its scope.

Note: To avoid this issue, people often make use of the self/that pattern to guarantee that they have access to their scope this, instead of the one provided by the caller.

Self pattern
Self pattern output

Now looking at the same example, but rewritten using an arrow function.

An arrow function using this

Let’s see the output.

Arrow function using this output

The output’s exactly what we would expect of the first function example. This happens because arrow functions don’t have their own this and arguments and, instead, make use of scope for everything.

arguments

A function logging its arguments returning an anonymous function that also logs its arguments

Here we define a function that logs the content of its arguments object and returns an anonymous function that does the same.

The output of the values of the argument for each function

The output is exactly what we would expect. This is because the value assigned to the arguments object is related to each function, so each new function will have its arguments object.

Looking at a similar example but using arrow functions.

A function logging its arguments returning an arrow function that also logs its arguments

Now we have the same example but, instead of returning an anonymous function, it returns an arrow function.

The output of the values of the argument for each function

As I mentioned above, arrow functions don’t have their own this and arguments. What happens here is that the arguments object used inside of the arrow function is the one from its scope, which, in this case, its the one from the function where it was returned.

Note: ES6 introduced us to rest parameters. Using rest parameters is preferred to using the arguments object, as every function and arrow function will have their one.

Using rest parameters
The output of using rest parameters for each function

Using bind, call and apply

Using apply with a function
The output of using apply with a function

This example works as intended. The object passed when using the call function is bound to the function this.

Using apply with an arrow function
The output of using apply with an arrow function

As you can see, the output of the hello property assigned to this is undefined because despite trying to assign it when using call, the arrow function has no this for this binding to work — also, since the global this has no hello property it will log undefined.

Arrow functions can’t act as a constructor

Constructor Function

As you can see above, to instantiate an object, we make use of the new keyword to call that function as a constructor. With arrow functions, this doesn’t work because arrow functions can’t be called as constructors.

An attempt of calling an arrow function as a constructor
The output of the failed attempt

Note: After ES6, we can leave the constructor functions behind and use a class.

Using a class

Note 2: Since arrow functions can’t be called as a constructor, trying to use the new.target inside of it will throw an error.

The output of the attempt of using new.target inside an arrow function

Arrow functions have no prototype

Using prototypes with a function and an arrow function
The output of each prototype

Arrow functions can’t be generators

Generator
An attempt of Generator with Arrow Function
The output of the attempt

To watch out for

Object literals

The name is being treated as a label
The output of the return of the arrow function
Since we wrapped with parentheses, now the key is treated as it should
The output of wrapping the object literal with parentheses

Conclusion

Despite all of this, arrow functions allow writing shorter functions, reducing the size and “noise” we had with functions. All we have to do is to be careful with some of the nuances mentioned throughout this article.

I hope you enjoyed and stay tuned for future posts.

JavaScript in Plain English

Learn the web's most important programming language.

Daniel Afonso

Written by

Software Engineer. Nerdy, loves to code and wants to learn everything.

JavaScript in Plain English

Learn the web's most important programming language.

More From Medium

More from JavaScript in Plain English

More from JavaScript in Plain English

More from JavaScript in Plain English

5 Secret features of JSON.stringify()

More from JavaScript in Plain English

More from JavaScript in Plain English

7 really good reasons not to use TypeScript

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade