2

形状由矩形继承。这种继承可以通过许多方法来完成。这里我使用了 apply() 和 call()。当 draw 方法是 child 时,从该方法中再次调用基类的 draw 方法。我通过两种方式完成了这件事。一种是制作基类的原型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 () 继承基类,我将面临什么问题?

4

2 回答 2

2

继承使您能够使用基类的方法(和属性),而不必在派生类中显式创建它们(或链接到它们)

您的“替代”方法将要求实现的每个方法Shape都通过每个派生类进行代理,即使该派生类没有专门化该方法。

使用原型可以避免这种情况,因为任何时候调用方法或访问派生类中不存在的属性时,JS 解释器都会自动遍历属性链,直到在超类中找到该方法。

于 2013-05-09T11:37:15.720 回答
0

一个区别是 Rectangle 类的“绘制”函数是一个实例变量;因此它将在Rectangle的每个实例中使用内存。

此外,如果您正在使用原型,并且您根本不想更改父方法的行为(例如,在您的第二个示例中, Rectangle 的 'draw' 方法除了 draw 方法之外什么都不做的 Shape ,那么您根本不必重新定义该方法- 当在矩形上调用“绘制”时,运行时将爬上原型链,并在 Shape 中找到正确的方法。

所以你的第二个例子可能是:

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;
于 2013-05-09T11:38:05.630 回答