简体   繁体   English

JavaScript类继承无限循环

[英]JavaScript class inheritance infinite 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 intent is to inherit from Person into Player then have that new child class call the parent's original constructor. 目的是从Person继承到Player然后让新的子类调用父的原始构造函数。 However, this causes an infinite loop. 但是,这会导致无限循环。 What am I doing wrong and why is the loop happening? 我做错了什么,为什么循环发生?

This line right here is your problem: 这一行就是你的问题所在:

Player.prototype = Person.prototype;

You want the prototype for Player to inherit from Person 's prototype, but not make them equal. 您希望Player的原型继承Person的原型,但不能使它们相等。 Currently, your code makes the Player and Person prototypes reference equal , so any changes to Player.prototype also affect the Person.prototype (effectively making them indistinguishable). 目前,您的代码使PlayerPerson原型引用相等 ,因此对Player.prototype任何更改也会影响Person.prototype (实际上使它们无法区分)。

You're looking for: 您正在寻找:

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

Object.create instantiates a new object with a given prototype without actually calling the constructor (unlike a regular new Person() call would do). Object.create使用给定的原型实例化一个新对象而不实际调用构造函数(不像常规的new Person()调用那样)。 This allows you to get a new object inheriting the Person prototype, which you can then modify for the specifics of a Player . 这允许您获取继承Person原型的新对象,然后您可以根据Player的细节进行修改。

EDIT : As suggested in the comments by Siddarth, an even better solution would be to set the constructor through a property descriptor : 编辑 :正如Siddarth的评论中所建议的,更好的解决方案是通过属性描述符设置constructor

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

This way, the newly created prototype will have its constructor property made non-configurable, non-enumerable and non-writable. 这样,新创建的原型将使其constructor属性不可配置,不可枚举且不可写。 This prevents you from accidentally changing it afterwards through an assignment (eg Player.prototype.constructor = Foo ) and it won't show up in Object.keys or a for..in loop. 这可以防止您在事后通过赋值意外更改它(例如Player.prototype.constructor = Foo ),它不会显示在Object.keysfor..in循环中。 Normally, this shouldn't matter much but it's a good practice. 通常,这应该不重要,但这是一个很好的做法。

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 may be better to just re use Parent constructor with the following 使用以下内容重新使用Parent构造函数可能更好

Person.call(this,args);

Because if you use something like this.parent()... you'll get an infinite loop when you inherit 3 levels deep. 因为如果你使用像this.parent()...这样的东西this.parent()...当你继承3级深度时,你会得到一个无限循环。

More on prototype and constructor functions here . 更多关于原型和构造函数的信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM