JavaScript undefined class inheritance loop

I have the following:

function Person() {
  console.log('person');
}

function Player() {
  this.personConstructor();
}

Player.prototype = Person.prototype;
Player.prototype.constructor = Player;
Player.prototype.personConstructor = Person.prototype.constructor;

new Player();

      

The goal is to inherit from Person

to Player

, and then for the new child class to call the parent's original constructor. However, this causes an endless loop. What am I doing wrong and why is the loop happening?

+3


source to share


2 answers


This line right here is your problem:

Player.prototype = Person.prototype;

      

You want the prototype for to Player

inherit from prototype Person

, but don't make them equal. Currently, your code is making the link Player

and the Person

link equal, so any changes to that Player.prototype

also affect Person.prototype

(actually making them indistinguishable).

You are looking for:

Player.prototype = Object.create(Person.prototype);

      



Object.create

instantiates a new object with a given prototype without actually calling the constructor (as opposed to a normal call new Person()

). This allows you to get a new object that inherits the prototype Person

, which you can then modify for specifications Player

.

EDIT . As suggested in the comments by Sidthert, an even better solution would be to set constructor

the descriptor via the property :

Player.prototype = Object.create(Person.prototype, {
    constructor: { value: Player }
});

      

Thus, the generated prototype will have a property constructor

that will be non-configurable, non-enumerable and non-writable. This will prevent accidentally changing it after assignment (for example Player.prototype.constructor = Foo

), and it won't show up in a loop Object.keys

or for..in

. It usually doesn't matter much, but it's good practice.

+4


source


function Person(args) {
  console.log('person');
  args=args||{};
  this.name=args.name||"no name";
}

function Player(args) {
//  this.personConstructor();
// I prefer 
  Person.call(this,args);
}

Player.prototype = Object.create(Person.prototype);
Player.prototype.constructor = Player;

console.log(new Player());
console.log(new Player({name:"Jon"}));

      

It might be better to just use the parent constructor with the following

Person.call(this,args);

      



Because if you use something like this.parent()...

you get an infinite loop when you inherit 3 levels deep.

Read more about prototype and constructor functions here .

0


source







All Articles