Jonathan Lucas
Jonathan Lucas

Reputation: 575

ES6 arrow functions not working on the prototype?

When ES6 Arrow functions don't seem to work for assigning a function to an object with prototype.object. Consider the following examples:

function Animal(name, type){
 this.name = name;
  this.type = type;
  this.toString = () => `${this.name} is a ${this.type}`;

}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog

Using the arrow function explicitly in the object definition works, but using the arrow functions with the Object.prototype syntax does not:

function Animal2(name, type){
  this.name = name;
  this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined

Just as a proof of concept, using the Template string syntax with Object.prototype syntax does work:

function Animal3(name, type){
  this.name = name;
  this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}

var myPet3 = new Animal3('Joey', 'Kangaroo');
console.log(myPet3.toString()); //Joey is a Kangaroo

Am I missing something obvious? I feel that example 2 should work logically, but I am puzzled by the output. I'm guessing it is a scoping issue, but I am thrown off by the output 'is a undefined'.

ES6 Fiddle

Upvotes: 57

Views: 23323

Answers (4)

Mohsen Sorkhpour
Mohsen Sorkhpour

Reputation: 1

It should be noted that the arrow function doesn't have this for itself and always the this keyword in each arrow function refers to lexical scope, so in your first example, the this keyword refers to the Animal class. In your 2nd example, the this keyword refers to the global scope. In the 3rd example, because the toString method belongs to the Animal class prototype, therefore it has access to the Animal class scope, in other words, the this keyword inside a prototype's methods refers to the prototype owner.

here there are some useful links:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

Upvotes: 0

HaiNguyen007
HaiNguyen007

Reputation: 1

arrow function is not have its own this , it resolved to this of closest function:

  • your 1st example: this resolve to this of Animal() function
  • your 2nd example: this resolve to global object window (because it isn't inside any function)
  • your 3rd example: this working as always expected because not using arrow funciton.

Upvotes: 0

Baskaran Ajiharan
Baskaran Ajiharan

Reputation: 508

Regular function returns a reference to the current JavaScript Object but the arrow function returns the reference to the global window object.

Regular functions are working well with objects using the new keyword. They have the constructor function by which values can be initialized during object creation. It can be managed using the prototype chaining but the arrow function does not have constructor function, prototype chaining. They are not working well with objects. They can not be used with the new keyword for assigning memory.

In your first example, you write your arrow key function inside the regular function, then you will get the output.

function Animal2(name, type){
    this.name = name;
    this.type = type;
}
Animal2.prototype.toString = function(){
    return () => `${this.name} is a ${this.type}`;
}

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()()); //Noah is a cat

Reference: Difference between regular function and arrow key function

Upvotes: 7

Amit
Amit

Reputation: 46323

Arrow functions provide a lexical this. It uses the this that is available at the time the function is evaluated.

It is logically equivalent to (the following isn't valid code since you can't have a variable named this):

(function(this){
   // code that uses "this"
 })(this)

In your 1st example the arrow function is within the constructor, and this points to the newly generated instance.

In your 3rd example, an arrow function isn't used and standard this behavior works as always (the this in the function scope).

In your 2nd example, you use an arrow function but at the scope it's evaluated, this is global / undefined.

Upvotes: 54

Related Questions