Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a revealing prototype pattern extent another revealing prototype pattern

I'm trying to use the revealing prototype patter to extend a "class". As an example I have an Animal and a Fish.

Here's what I'd like to be able to to:

  • Fish to Inherit the prototype from Animal
  • Override members of Animal if needed
  • Add new members to the Fish prototype
  • Do all this while still using the revealing prototype pattern for both "classes"

I can create the Animal "class":

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
  };
}();

And I can create a Fish "class" that inherits from Animal:

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


Fish.prototype = new Animal();

The prototype for the Fish is where I'm running into trouble. Is it possible to use the revealing prototype pattern for Fish and still inherit the prototype from Animal and override Animal if needed? (I'm not completely opposed to using a third party library to do this, but I'd prefer not to.) For example, how could I override eat() and add a new function to Fish called swim?

Edit:

Here's what I've come up with. This seems to do what I need. Am I missing anything?

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());

Edit:

In the answer I accepted, one of the main points was to not use the new keyword. So I researched the difference between the new keyword and Object.create(). If I understand things correctly, they both do basically the same thing, but Object.create() will not call the objects constructor while the new keyword will. If you need to inherit something that is defined in the constructor, you'll need to use the new keyword or move that member to the prototype.

Here's a plunk that I used to experiment with this some more: http://plnkr.co/edit/322WB4jyCJberABbb0P0

like image 925
Jeff Avatar asked Jun 28 '26 02:06

Jeff


1 Answers

Am I missing anything?

Yes.

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. You'd create a new instance here, however what you want is get the eat method from the base.prototype and call that on your Fish instance.

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);
like image 172
Bergi Avatar answered Jun 30 '26 16:06

Bergi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!