[英]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). 目前,您的代码使
Player
和Person
原型引用相等 ,因此对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.keys
或for..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.