我正在学习 JavaScript。
我发现了流行的扩展功能:
function extend(Child, Parent) {
var F = function() { }
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.superclass = Parent.prototype
}
让我们创建 3 个类
function foo() {}
foo.prototype.identify = function() {
return "I'm a foo";
}
function bar() {}
extend(bar, foo)
bar.prototype.identify = function() {
return "I'm a bar and " +
this.constructor.superclass.identify.apply(this, arguments);
}
function zot() {}
extend(zot, bar)
zot.prototype.identify = function() {
return "I'm a zot and " +
this.constructor.superclass.identify.apply(this, arguments);
}
因此我们有以下继承方案:
foo->bar->zot
让我们编写一些代码:
f = new foo();
alert(f.identify()); // "I'm a foo"
b = new bar();
alert(b.identify()); // "I'm a bar and I'm a foo"
z = new zot();
alert(z.identify()); // stack overflow
丢失的行产生
Uncaught RangeError: Maximum call stack size exceeded(…)
您能详细解释一下发生了什么吗?
最佳答案
因为一旦 identify.apply(this)
被调用两次(就像在 zot
中,与 bar
不同),this
将指向两个函数上的同一个实例,并将无休止地调用自己的 identify()
方法。
相反,尝试显式指向基本 identify
方法:
function extend(Child, Parent) {
var F = function() {}
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.superclass = Parent.prototype
}
function foo() {}
foo.prototype.identify = function() {
return "I'm a foo";
}
function bar() {}
extend(bar, foo)
bar.prototype.identify = function() {
return "I'm a bar and " +
bar.superclass.identify.apply(this, arguments);
}
function zot() {}
extend(zot, bar)
zot.prototype.identify = function() {
return "I'm a zot and " +
zot.superclass.identify.apply(this, arguments);
}
var f = new foo();
alert(f.identify()); // "I'm a foo"
var b = new bar();
alert(b.identify()); // "I'm a bar and I'm a foo"
var z = new zot();
alert(z.identify()); // "I'm a zot and I'm a bar and I'm a foo"
参见Fiddle
关于javascript - 当我调用 this.constructor.superclass.someMethod 时,超出最大调用堆栈大小会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40842246/