loading...

Using arrow function to define a method

kayut profile image Kayut ・1 min read

Hi,

I started learning React and right now I'm a bit confused about where to use Arrow-function to define a method and where not to use it.

First let's check object literals

This code works:

const person = {
  points: 23,
  score() {
    return this.points++;
  }
};

person.score(); // Works

But the bellow code doesn't work, because we defined the score() method as an arrow-function:

const person = {
  points: 23,
  score: () => {     // Arrow function
    return this.points++;
  }
};

person.score(); // Doesn't work

Take away: Never define methods in an object literal via arrow-function.
Is the above statement correct?

What about JavaScript classes?

This code works:

class Dog {
    constructor(name, bread) {
        this.name = name;
        this.bread = bread;
    }

    bark() {
        return `Bark Bark! My name is ${this.name}`;
    }
}
const mini = new Dog('Mini', 'Spitz');
mini.bark();

And the bellow code, which uses arrow-function syntax to define the bark() method works too:

class Dog {
  constructor(name, bread) {
    this.name = name;
    this.bread = bread;
    this.bark = () => {     // Arrow function
      return `Bark Bark! My name is ${this.name}`;
    }
  }
}
const mini = new Dog('Mini', 'Spitz');
mini.bark();

Take away: It's fine to define methods in a Class via arrow-function.

Is the above statement correct?

What about React classes (class components)?

It is even recommended to use arrow-functions for defining methods inside React classes as a way to create "auto-binding" methods, e.g. methods that could be used by event handlers but that stayed bound to the class.

Is the above statement correct?

Posted on Jan 18 '19 by:

Discussion

markdown guide
 

The lamda function, aka the fat arrow has one unique property that separates itself from a normal function. The lamda does not bind the object which called it to the this keyword. A normal javascript function binds the caller to the this keyword.

const person = {
  points: 23,
  score: () => {     // Arrow function
    return this.points++;
  }
};

person.score(); // Doesn't work

That is why this example doesn't work, the lamda has context of what this is.

Now, if you like the syntax of the lamda function, you can explicitly bind an object to the this value by using the .bind() method.

const person = {
  points: 23,
  score: () => {     // Arrow function
    return this.points++;
  }.bind(person),
};

person.score(); // works

There are most likely many who could explain the concept way better then I can. Hope that helps.

In regards to your other question about defining functions in the constructor...

In my opinion, I would NOT recommend assigning functions in the constructor of a class unless you were using some sort of thunk pattern. The reason being that every time the class is instantiated, the class has to recreate those functions in memory which is a waste. If you define a function outside of the classes constructor, the function gets attached to the classes prototype chain which is much more efficient.

 

Are the following statements correct?

  1. Never define methods in an object literal via arrow-function.

  2. It's fine to define methods in a Class via arrow-function.

  3. In React it is even recommended to use arrow-functions for defining methods inside React classes as a way to create "auto-binding" methods, e.g. methods that could be used by event handlers but that stayed bound to the class.

 

I think it's more important to be consistent. If you are using arrow functions to define Class methods, then all class methods should be arrow functions. Similarly if you are using arrow functions for object literals then you should stick with them.

Though, for best practices I usually try to stick with the constraints you have defined. And then keep them consistent across the project.