DEV Community

loading...
Cover image for why you shouldn't use arrow functions?

why you shouldn't use arrow functions?

blessingartcreator profile image Blessing Hirwa ・2 min read

Who doesn’t love the simplicity of arrow functions? Introduced as part of the ECMAScript 6, arrow functions went viral. The new syntax to declare functions saves us time and enhancing clarity in many situations, removing all the distracting, unnecessary, chunk that usually came with declaring a JS function 😫. In this article we'll talk more about when we should and not use arrow functions, so hold tight and continue with me until the end to avoid confusion.

Regular funciton declaration

function holidays(){ 
return "Merry Christmas and a happy new year 😀!"
}
Enter fullscreen mode Exit fullscreen mode
const result = list.map(function(item) { return item; })
Enter fullscreen mode Exit fullscreen mode

With Es6 functions

const holidays = () => "Merry Christmas and a happy new year 😀!"
Enter fullscreen mode Exit fullscreen mode
const result = list.map((item) => item)
Enter fullscreen mode Exit fullscreen mode

Isn't it lovely? In any case, we have to be cautious as the difference between them is not only just syntax, so we can't use it in every situation.

So when is using arrow functions not advisable 🙄?

1. Object methods

const post= {
likes: 0,
like: () => {
this.likes++;
}
}
Enter fullscreen mode Exit fullscreen mode

In the example above, it would be instinctive to think that every time we call post.like() the property post.likes would increase by one, initially from 0 to 1.
Unfortunately, this is not the case, the value of likes will sadly remain the same and this post will never get to be popular.

Invoking the method like() would simply attempt to increment the property likes on the global window object.

However, if instead, we use the traditional syntax:

const post = {
likes: 0,
like: function() {
this.likes++;
}
}
Enter fullscreen mode Exit fullscreen mode

2. Object Prototype

Similar to the example above, object prototypes will evaluate this as the global window object, like in the following example:

class Post {
constructor(title) {
this.title = title;
this.shared = false;
}
};

Post.prototype.share = () => {
return this.shared = true;
};
Enter fullscreen mode Exit fullscreen mode

Similarly, in the previous case, the method share() won’t work due to the enclosed scope to the window object. And again the solution will look familiar:

Post.prototype.share2 = function() { return this.shared = true; };
Enter fullscreen mode Exit fullscreen mode

In addition to what we saw above here are some limitations of arrow functions:

  • Does not have its own binding to this or super
  • Should not be used as an event handler, a method of an object, a method of a class, or a prototype method, or when you have a function that uses the arguments object.
  • Not suitable for call, apply and bind methods, which generally rely on establishing a scope
  • Cannot be used as a constructor
  • Cannot use yield within its body

Taken from MDN

To be continued...

Thank you for taking your time and read this post, hope you enjoyed it. Let me know what you think in the comments and don't forget to connect with me or hit me up on Twitter, Instagram and Linkedin. Once again, Merry Christmas and a happy new year of 2021 🌲.

Discussion (18)

pic
Editor guide
Collapse
lukeshiru profile image
▲ LUKE知る

It is true that when using arrow functions, it uses the upper scope's this, but...

1. Object methods:

Ideally, you shouldn't use function either, this is far cleaner:

const post = {
    likes: 0,
    like() {
        this.likes++;
    }
};
Enter fullscreen mode Exit fullscreen mode

2. Object Prototype:

Ideally, you shouldn't alter an object prototype, so in here you can omit function again::

class Post {
    constructor(title) {
        this.title = title;
        this.shared = false;
    }
    share() {
        this.shared = true;
    }
}
Enter fullscreen mode Exit fullscreen mode

Or you can even use arrow functions, if you plan yo just return a value:

class Post {
    #shared = false;
    constructor(title) {
        this.title = title;
    }
    share() {
        this.#shared = true;
    }
    wasShared = () => this.#shared;
}
Enter fullscreen mode Exit fullscreen mode

You could just avoid using classes and using this altogether, so you can always use arrow functions, instead of avoiding using them in certain scenarios. The same examples mentioned above using functional programming instead of classes look something like this:

// Generic functions
const set = property => value => source => ({ ...source, [property]: value });
const get = property => source => source[property];

// Post related functions
const setLikes = set("likes");
const addLikes = likes => post => setLikes(post.likes + likes)(post);
const share = set("shared")(true);
const addLike = addLikes(1);

// Use case
const post = {
    title: "Example",
    likes: 0,
    shared: false
};

addLike(post); // Returns { title: "Example", likes: 1, shared: false }
share(post); // Returns { title: "Example", likes: 0, shared: true }

// No mutations, yey! 🎉
Enter fullscreen mode Exit fullscreen mode
Collapse
blessingartcreator profile image
Blessing Hirwa Author

That's a good one.

Collapse
matjones profile image
Mat Jones

As far as your first point, that's literally just syntax sugar/shorthand for a regular function declaration.

Collapse
saba1121 profile image
Saba1121

const holidays = () => return "Merry Christmas and a happy new year 😀!"

In this example you dont really need word "return". Arrow functions which are one line and dont use curly braces automatically return result. So it should be like this:

const holidays = () => "Merry Christmas and a happy new year 😀!"

Collapse
blessingartcreator profile image
Blessing Hirwa Author

I wanted to be more clear. But yours also works well.

Collapse
lucgauer profile image
Lucas Gauer

Usage of return explicitly into a single statement arrow function (without the curly brackets), is actually a syntax error 🙁.

Collapse
blessingartcreator profile image
Blessing Hirwa Author

I also changed it lol.

Collapse
baenencalin profile image
Calin Baenen

Actually, you said arrow functions don't have arguments.
That is false.

const add = (...nums) => {let i = 0; for(let num of nums) i += num; return i;}
Enter fullscreen mode Exit fullscreen mode
Collapse
blessingartcreator profile image
Collapse
baenencalin profile image
Calin Baenen

Oh, you meant the keyword (you should probably specify that in the post).

Thread Thread
blessingartcreator profile image
Blessing Hirwa Author

Yeah, I just added it now.

Collapse
chrisburkssn profile image
Chris Burks

Thanks for the info. Looking for the continuation.
Small note: I think there is a typo for your first example Object methods. You mention "the property post.claps would increase by one". However, there is not property "claps" in the code example. There is "likes" though.

At any rate, good stuff here and thanks again for posting.

Collapse
blessingartcreator profile image
Blessing Hirwa Author

ohhh I didn't catch that. Thanks for correcting

Collapse
tonyscruze profile image
TonySCruze

Great article. Thanks 🙂

Collapse
lyrod profile image
Lyrod

For object methods, you should use the "like() {}" syntax

Collapse
oreste profile image
Oreste Abizera

cool stuff! Actually, I didn't know this 😍(before reading this post)

Collapse
blessingartcreator profile image
Blessing Hirwa Author

Glad it helped 😁

Collapse
hasnaindev profile image
Muhammad Hasnain

Please replace "why" with "when" in your post as it is very misleading, thanks.