Shape由矩形继承。这种继承可以通过许多方法完成。这里我使用了apply()和call()。当draw方法是child被调用时,从那个方法再次调用基类的draw方法。我以两种方式完成了这件事。一个是制作基类的原型绘制方法,另一个是使用apply()和call()方法 第一种方法:
function Shape () {
this.name='Shape';
this.getName = function () {
return this.name;
};
this.draw = function () {
alert("Something");
};
}
function Rectangle () {
Shape.apply(this);
var X=this.draw;
this.name = 'rectangle';
this.id=500;
this.draw = function () {
X.call(this);
};
}
第二种方法:
function Shape () {
this.name='Shape';
this.id=100;
this.getName = function () {
return this.name;
};
}
Shape.prototype.draw = function() {
alert("Something");
};
function Rectangle () {
this.name = 'rectangle';
this.id=200;
this.draw = function () {
Shape.prototype.draw.call(this);
};
}
Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;
这两种方法都做类似的事情(在提供输出的情况下)。我知道通过使用apply()和call()方法,我无法直接获取基类原型的访问权限。使用apply()和call()的继承对我来说似乎不那么复杂。如果两者都相同那么为什么人们不使用apply()和call()那么多?为什么我需要使用原型?如果我不使用原型并使用apply()和call()继承基类,我将面临什么问题?
答案 0 :(得分:2)
继承使您能够使用基类的方法(和属性),而无需在派生类中显式创建它们(或链接到它们)。
您的“备用”方法需要每个方法Shape
实现通过每个派生类进行代理,即使该派生类没有专门化该方法
使用原型可以避免这种情况,因为无论何时调用方法或访问派生类中不存在的属性,JS解释器都会自动遍历属性链,直到它在超类中找到该方法。
答案 1 :(得分:0)
一个区别是Rectangle类的'draw'函数是一个实例变量;因此它将在 Rectangle的每个实例中使用内存。
此外,如果您正在使用原型,并且您根本不想更改父方法的行为(例如,在第二个示例中,Rectangle的'draw'方法除此之外不会执行任何操作Shape的draw方法,那么你不必重新定义方法 - 当在矩形上调用'draw'时,运行时将爬上原型链,找到正确的链接形状
所以你的第二个例子可能是:
function Shape () {
this.name='Shape';
this.id=100;
}
Shape.prototype.getName = function () {
return this.name;
};
Shape.prototype.draw = function() {
alert("Something");
};
function Rectangle () {
this.name = 'rectangle';
this.id=200;
}
// Notice we don't repeat "getName" since it is defined in
// the parent class, and there is no need to do something else.
// In case you actually want to "override" the behavior
Rectangle.prototype.draw = function () {
Shape.prototype.draw.call(this);
alert("Do something else than Shape");
};
Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;