我认为我对如何在JavaScript中正确扩展类有了很好的理解,但是在扩展子类时,当我覆盖一个方法时,我会遇到无限循环,并从子类调用父方法。我做错了,或者你不应该在JavaScript中以这种方式进行子类化。
有人可以帮助教育我吗?
var Grand = function() {
this.test();
};
Grand.prototype.constructor = Grand;
Grand.prototype.test = function() {
console.log( "Grand!")
};
var Parent = function() {
this.supr.constructor.call( this );
};
Parent.prototype = Object.create( Grand.prototype );
Parent.prototype.constructor = Parent;
Parent.prototype.supr = Grand.prototype;
Parent.prototype.test = function() {
this.supr.test.call( this );
console.log( "Parent!" );
};
var Child = function() {
this.supr.constructor.call( this );
};
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
Child.prototype.supr = Parent.prototype;
Child.prototype.test = function() {
this.supr.test.call( this );
console.log( "Child!" );
};
var g = new Grand(); // Outputs "Grand!"
var p = new Parent(); // Outputs "Grand!" "Parent!"
var c = new Child(); // Error: Endless Loop!

我希望控制台能够登录" Grand!"," Parent!"," Child!"当实例化一个新的Child()时,我会得到一个无限循环。
我来自ActionScript背景,因此在JavaScript中创建类仍然会让我产生一些曲线球。感谢您的帮助!
答案 0 :(得分:1)
我建议切换到es6。这种原型设计可能是一个真正的混乱,更难以跟踪。但是如果你在浏览器中需要这个,你应该将代码转换为es5 whit babel等。只要你有一个最新的版本,在Node env就可以了。一些最新的浏览器也支持它
class Grand {
constructor() {
this.test()
}
test() {
console.log( "Grand!")
}
}
class Parent extends Grand {
test() {
super.test()
console.log( "Parent!" )
}
}
class Child extends Parent {
test() {
super.test()
console.log( "Child!" )
}
}
let g = new Grand(); // Outputs "Grand!"
let p = new Parent(); // Outputs "Grand!" "Parent!"
let c = new Child(); // Outputs "Grand!" "Parent! "child!"
它不仅更具可读性,而且代码更少,更容易理解
答案 1 :(得分:0)
问题在于这段代码:
var Parent = function() {
this.supr.constructor.call( this );
};
考虑执行此代码时会发生什么:
var c = new Child();
此处this
是变量c
,因此this.supr.constructor
始终是父代的构造函数,因为这些代码行中的设置:
Child.prototype.supr = Parent.prototype; // i.e. this.supr = Parent.prototype
Parent.prototype.constructor = Parent; // i.e. this.supr.constructor = Parent
因此,当Child的构造函数调用this.supr.constructor.call( this );
时,它执行Parent
函数,父函数再次执行this.supr.constructor.call( this );
,导致调用Parent
函数再次,导致无限循环。
修复是按如下方式调用基类函数:
var Child = function() {
Child.prototype.supr.constructor.call( this );
};