JavaScript类继承无限循环
我有以下资料:JavaScript类继承无限循环,javascript,Javascript,我有以下资料: function Person() { console.log('person'); } function Player() { this.personConstructor(); } Player.prototype = Person.prototype; Player.prototype.constructor = Player; Player.prototype.personConstructor = Person.prototype.constructor;
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();
其目的是从
Person
继承到Player
中,然后让新的子类调用父类的原始构造函数。但是,这会导致无限循环。我做错了什么?为什么会发生循环?这一行就是你的问题:
Player.prototype = Person.prototype;
您希望Player
的原型继承自Person
的原型,但不使它们相等。目前,您的代码使Player
和Person
原型引用相等,因此对Player.prototype
的任何更改也会影响Person.prototype
(有效地使它们无法区分)
您正在寻找:
Player.prototype = Object.create(Person.prototype);
使用给定原型实例化新对象,而不实际调用构造函数(与常规的newperson()
调用不同)。这允许您获得继承Person
原型的新对象,然后您可以根据播放器的具体情况对其进行修改
编辑:正如Siddarth在评论中建议的那样,更好的解决方案是通过以下方式设置构造函数
:
这样,新创建的原型将使其构造函数
属性变得不可配置、不可枚举和不可写。这可以防止您在以后通过赋值(例如Player.prototype.constructor=Foo
)意外更改它,并且它不会显示在对象.keys
或for.
循环中。通常情况下,这并不重要,但这是一个很好的做法
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"}));
最好是将父构造函数与以下内容一起重用
Person.call(this,args);
因为如果你使用类似于this.parent()…
的东西,当你继承3层时,你会得到一个无限循环
更多关于原型和构造函数的信息。Player.prototype=Person.prototype代码>应该是Player.prototype=Object.create(Person.prototype)代码>…这是因为当您将Player.prototype
作为对Person.prototype
的引用,然后将Player
分配给Player.prototype.constructor
时,实际上是将其分配给了Person.prototype.constructor
。因此,personConstructor
实际上是对Player
的引用,而不是Person
,因此创建了无限调用循环。this.personConstructor()
工作正常,不需要。如果要传递相同的this
,则调用。然而,Person.call(this,args)
确实是一个更通用的解决方案,它不需要额外的Player.prototype.personConstructor
定义。@MattiasBuelens正确,我更改了答案。我将创建该对象。创建(Person.prototype,{constructor:{value:Player}}),别忘了在子构造函数中调用父构造函数。@Siddharth哦,对了,您可以将一组属性描述符传递给对象。创建。我个人更喜欢使用经典赋值或类似于.extend
的方法来向原型添加属性。虽然属性描述符可能更好,但您的解决方案可以防止原型的构造函数
稍后(意外)被更改。谢谢你的提示!
Person.call(this,args);