问题
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