Javascript Prototypal inheritance with Multiple Objects

五迷三道 提交于 2019-12-11 07:43:55

问题


Say I have 5 Objects

Callback
Perishable
Object1
Object2
Object3

Object1 needs to extend the Callback but not the Perishable object, whereas Object 2 should extend both and Object 3 should extend Perishable but not callback.

I know this works...

Object1.prototype = new Callback();
Object3.prototype = new Perishable();

but how would I do something like (I know this isnt working)

Object2.prototype = new Callback() && new Perishable();

回答1:


If you don't want any external dependencies, you can use this implementation of extend:

function __extends(d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    var a = function(){}; a.prototype = new b();
    for (var p in a.prototype) d.prototype[p] = a.prototype[p];   
};

Example:

var animal = function(){

};

animal.prototype.run = function(){
     console.log("running");   
};

var feline = function(){

};

feline.prototype.hunt = function(){
     console.log("hunting");   
};

var cat = function(){

};

__extends(cat, animal);
__extends(cat, feline);

var scaryCat = new cat();

scaryCat.run();

scaryCat.hunt();

Fiddle: http://jsfiddle.net/apqwf93a/9/




回答2:


You can use extend function from Underscore.js library.

The code would look like this:

_.extend(Object1.prototype, Callback.prototype);
_.extend(Object1.prototype, Perishable.prototype);

Here's JS fiddle: http://jsfiddle.net/yb7kkh4e/2/




回答3:


Usually when you want to extend multiple objects you have to look if your design is correct. Is the object the other object?

For example a Cat is an Animal and a Cat can move. To extend the Cat from Movable would be wrong because the Cat is not a Movable it can move so it should implement Movable or leave default implementation of Movable.

The example of Cat Feline and Animal is fine but could be solved without multiple inheritance. A Cat is a Feline and a Feline is an Animal so no reason for Cat to both inherit from Feline and Animal you could have Cat inherit from Feline and Feline from Animal.

The chosen answer deals with the prototype part of mix ins (implements) but doesn't cover how to initialize instance specific members. Here is the mix in part of the following answer that does:

Multiple inheritance with mix ins

Some things are better not to be inherited, if a Cat can move and than a Cat should not inherit from Movable. A Cat is not a Movable but rather a Cat can move. In a class based language Cat would have to implement Movable. In JavaScript we can define Movable and define implementation here, Cat can either override, extend it or us it's default implementation.

For Movable we have instance specific members (like location). And we have members that are not instance specific (like the function move()). Instance specific members will be set by calling mxIns (added by mixin helper function) when creating an instance. Prototype members will be copied one by one on Cat.prototype from Movable.prototype using the mixin helper function.

var Mixin = function Mixin(args){
  var i, len;
  if(this.mixIns){
    i=-1;len=this.mixIns.length;
    while(++i<len){
        this.mixIns[i].call(this,args);
      }
  }  
};
Mixin.mix = function(constructor, mix){
  var thing
  ,cProto=constructor.prototype
  ,mProto=mix.prototype;
  //no extending, if multiple prototype uhs
  // have members with the same name then use
  // the last
  for(thing in mProto){
    if(Object.hasOwnProperty.call(mProto, thing)){
      cProto[thing]=mProto[thing];
    }
  }
  //instance intialisers
  cProto.mixIns = cProto.mixIns || [];
  cProto.mixIns.push(mix);
};
var Movable = function(args){
  args=args || {};
  //demo how to set defaults with truthy
  // not checking validaty
  this.location=args.location;
  this.isStuck = (args.isStuck===true);//defaults to false
  this.canMove = (args.canMove!==false);//defaults to true
  //speed defaults to 4
  this.speed = (args.speed===0)?0:(args.speed || 4);
};
Movable.prototype.move=function(){
  console.log('I am moving, default implementation.');
};
var Animal = function(args){
  args = args || {};
  this.name = args.name || "thing";
};
var Cat = function(args){
  Animal.call(args);
  //if an object can have others mixed in
  //  then this is needed to initialise 
  //  instance members
  Mixin.call(this,args);
};
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Mixin.mix(Cat,Movable);
var poochie = new Cat({
  name:"poochie",
  location: {x:0,y:22}
});
poochie.move();


来源:https://stackoverflow.com/questions/26784204/javascript-prototypal-inheritance-with-multiple-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!