一个揭示原型模式可以扩展另一个揭示原型模式

时间:2014-03-05 23:52:59

标签: javascript design-patterns

我正在尝试使用揭示原型模式来扩展“类”。举个例子,我有动物和鱼。

以下是我希望能够:

  • Fish从Animal继承原型
  • 如果需要,覆盖动物的成员
  • 将新成员添加到Fish原型
  • 在为“两个类”
  • 使用显示原型模式的同时完成所有这些操作

我可以创建动物“类”:

var Animal = function(data) {
  this.name = ""
  this.color = "";
  this.weight = 0;
};


Animal.prototype = function() {
  var eat = function() {
    document.write(this.name + " is eating.<br>");
  }

  return {
    constructor: Animal,
    eat: eat
  };
}();

我可以创建一个继承自Animal的鱼类“

var Fish = function(data) {
  this.isSwimming = false;
};


Fish.prototype = new Animal();

鱼的原型是我遇到麻烦的地方。是否有可能使用Fish的显示原型模式并仍然从Animal继承原型并在需要时覆盖Animal? (我并不完全反对使用第三方库来执行此操作,但我不愿意这样做。)例如,我怎样才能覆盖eat()并向Fish添加一个名为swim的新函数?

编辑:

这就是我想出的。这似乎做我需要的。我错过了什么吗?

Fish.prototype = new function(proto) {
  var base = proto.constructor;

  var eat = function(data) {
    new base().eat (data);//This is just to show you can call the base. If needed.
    document.write("fish eating.<br>");
  };

  var swim = function(){
    document.write("fish is swimming.<br>");
  };

  var thisProto = {
    constructor: Fish,
    eat: eat,
    swim: swim
  };

  for (var propt in thisProto) {
    proto[propt] = thisProto[propt];
  }

  return proto;
}(new Animal());

编辑:

在我接受的答案中,其中一个要点是不使用new关键字。所以我研究了new关键字和Object.create()之间的区别。如果我理解正确,它们基本上都做同样的事情,但是Object.create()不会在新关键字出现时调用对象构造函数。如果您需要继承构造函数中定义的内容,则需要使用new关键字或将该成员移动到原型。

以下是我用来试验其中的更多内容:http://plnkr.co/edit/322WB4jyCJberABbb0P0

1 个答案:

答案 0 :(得分:2)

  

我错过了什么吗?

new function(proto) {

Do not use new

new base().eat (data);//This is just to show you can call the base. If needed.

Do not use new。您可以在此处创建新实例,但是您想要的是从Fish实例上的eatcall获取base.prototype方法。

proto = new Animal()

Do not use new


Fish.prototype = (function(super) {
  var proto = Object.create(super);

  function eat(data) {
    super.eat.call(this, data);
    document.write("fish eating.<br>");
  }
  function swim(){
    document.write("fish is swimming.<br>");
  }

  proto.constructor = Fish;
  proto.eat = eat;
  proto.swim = swim;

  return proto;
})(Animal.prototype);