Differences between defining object methods using Arrow Function and Function Expression

Asked

Viewed 125 times

6

About "flammable" methods outside objects, I can say that these three forms below act in the same way within my code?

Examples:

var barquinho = {
  pedro: () => {
    console.log("a");
  },
  tiago: function() {
    console.log("b");
  },
  joao() {
    console.log("c");
  }
};

These are the ways I know to define methods within objects.

I would like to know what the differences are between the three above, as I use the same form to invoke them:

barquinho.pedro();
barquinho.tiago();
barquinho.joao();

1 answer

4


"Methods" such as Arrow functions

The difference is that in the first case, you are using a Arrow Function to define the method. See this question and the documentation to learn more about this type of function.

In summary, the Arrow Function doesn’t have his own this Binding, that is, it does not possess the this associated with the object to which it is contained (remember that every function is associated with some object). Exactly why it does not make much sense to use it to define a method, since, by definition, methods are always associated with the idea of some "object" or "instance". Basically, the this of Arrow Function shall be inherited from the immediately higher lexical scope.

const obj = {
  arrow: () => {
    console.log(this.toString()); // [object Window]
    console.log(this === obj); // false
    console.log(this === window); // true
  }
};

obj.arrow();

How we use a Arrow Function to define the "method" arrow, this will inherit the value this of the lexical scope above. As objects have no lexical scope, the this refers to the overall scope, which in browsers is window. It is also worth noting that, in strict mode, the behavior of the this global is a little different.

Precisely why it is not worth using Arrow functions everywhere, contrary to what many people seem to do. What’s the point of using Arrow Function to define a method, and you will not even be able to access, through the this, other properties of this object? Precisely why I put the term "methods" in quotation marks in the title of this section.

Methods with Function Expression and the new rating

In the other two examples function expression to define the methods. In this case, the this refers to the object in which the methods are contained. Let’s see:

const obj = {
  a: function() {
    console.log(this.toString()); // [object Object]
    console.log(this === obj); // true
    console.log(this === window); // false
  },
  
  b() {
    console.log(this.toString()); // [object Object]
    console.log(this === obj); // true
    console.log(this === window); // false
  }
};

obj.a();
console.log('---');
obj.b();

The only difference between a and b, in the example above, is that b uses a notation introduced in Ecmascript 2015 (ES6) to facilitate the definition of Function Expressions in objects. Although it is a syntactic sugar, there is a subtle difference:

As opposed to defining a function using the "old" notation (in the above example, method a) function expression, when using the new syntax (in the above example, method b), cannot be used as a manufacturer.

So we could, in theory, do this:

const obj = {
  functionExpression: function() { /* ... */ }
}; 

new obj.functionExpression(); // Totalmente válido!

However, functions defined with the new notation are not constructible:

const obj = {
  newMethodDefinitionSyntax: function() { /* ... */ }
}; 

new obj.newMethodDefinitionSyntax(); // TypeError: obj.newMethodDefinitionSyntax is not a constructor

Precisely because of this, when using the new notation, properties such as prototype (not to be confused with __proto__) will not be defined, since they only make sense in the case of construction functions.

Otherwise, the difference is merely syntactic. Learn more about this syntactic sugar in documentation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.