在尝试将Java应用程序移植到JavaScript时,我正在尝试以下继承技术:
var grandchild = new Grandchild();
Function.prototype.extend =
function(parent) {
var parentPrototype = parent.prototype;
this.prototype = Object.create(parentPrototype);
this.prototype.superPrototype = parentPrototype;
this.prototype.superConstructor = parent;
this.prototype.constructor = this;
}
;
function Parent(){
this.doStuff();
}
Parent.prototype.doStuff =
function() {
}
;
Child.extend(Parent);
function Child(){
this.superConstructor.call(this);
}
Child.prototype.doStuff = function() {
this.superPrototype.doStuff.call(this);
}
Grandchild.extend(Child);
function Grandchild(){
this.superConstructor.call(this);
}
Grandchild.prototype.doStuff = function() {
this.superPrototype.doStuff.call(this);
}
它适用于一个级别的继承(即var child = new Child()
)但是new Grandchild()
会抛出一个Uncaught RangeError: Maximum call stack size exceeded
,因为它会在function Child()
上无限递归。
this.superConstructor.call(this)
和this.superPrototype.doStuff.call(this)
,而无需在直接父级上进行无限递归?当我在调用中指定超类时,它可以工作,但我不想这样做:
function Child(){
Parent.call(this);
}
Child.prototype.doStuff = function() {
Parent.prototype.doStuff.call(this);
}
function Grandchild(){
Child.call(this);
}
Grandchild.prototype.doStuff = function() {
Child.prototype.doStuff.call(this);
}
答案 0 :(得分:1)
好。事情就是这样:在JS中,SELECT *
FROM firstTable
WHERE EXISTS (SELECT TOP(1) 1
FROM secondTable
WHERE firstTable.name = secondTable.name
AND (
firstTable.age = secondTable.age
OR
(firstTable.age IS NULL AND secondTable.age IS NULL)
)
);
和this
一起是最难掌握的概念。
当您致电new
时,new GrandChild()
是什么?
this
是一个对象,其this
设置为 __proto__
指向的对象。我们将调用此版本的GrandChild.prototype
,this
。
gc_this
现在执行GrandChild()
。我们也可以说它执行this.superConstructor.call(this);
,因为我们理论上将gc_this.superConstructor.call(gc_this);
中的this
重命名为Grandchild()
。
上述执行调用gc_this
并具有执行Child()
的相同效果。唯一的区别是,由于我们已将new Child()
传递给它,因此它不会返回任何内容,而 gc_this
中的所有this
都已替换为Child()
。 强>
好的,到目前为止一切顺利。没问题。
但现在开始出现问题:由于gc_this
中的所有this
都已替换为Child()
,因此gc_this
中的代码已更改为:
Child()
这是我们在function Child(){
gc_this.superConstructor.call(gc_this);
}
到this
内重命名 GrandChild()
时看到的完全行。
因此,这最终会导致无限递归。
在JS中实现多级经典继承的唯一方法是直接使用静态类名,而不是依赖于动态设置的自定义属性。
如果您希望获得有关该主题的更多信息,我建议您可以查看:http://www.javascripttutorial.net/javascript-prototype/