"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.