multiple inheritance question
I'm messing around with the prototype chain and noticed something I can't explain. I'm still learning all of this, so it's probably a mistake i've made. I'm trying to do some multi-inheritance, like so many others. I noticed the prototype object looks a lot like a hash/dictionary, I thought, why not use something like underscore.extend to merge multiple prototype objects together as one.
function A(){this.value="A";};
A.prototype.funcA = function (){console.log(this.value);}
function B(){this.value="B";};
B.prototype.funcB = function (){console.log(this.value);}
function C(){
// fix constructor
this.constructor = C;
// 'inherit' properties
A.call(this);
B.call(this);
};
// gobble up the prototype chains of A and B
C.prototype = new underscore.extend(A.prototype,B.prototype);
C.prototype.funcC = function (){console.log(this.value);}
var c = new C();
> c instanceof C
true
> c instanceof A
true
> c instanceof B
false
I'm really surprised to get a true at all here. Can anyone explain what's going on here?
UPDATE I removed underscore's extend method from the code, as suggested, and this works a lot better. thanks!
function extend(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};
function A(){this.value="A";};
A.prototype.funcA = function (){console.log(this.value);}
function B(){this.value="B";};
B.prototype.funcB = function (){console.log(this.value);}
function C(){
this.constructor = C;
A.call(this);
B.call(this);
};
var destination = {};
d开发者_如何学运维estination = extend(destination,A.prototype);
destination = extend(destination,B.prototype);
C.prototype = destination;
C.prototype.funcC = function (){console.log(this.value);}
var c = new C();
> c
{ constructor: [Function: C], value: 'B' }
> c instanceof A
false
> c instanceof B
false
> c instanceof C
true
There is no multiple inheritance in JavaScript, because one object can have only one prototype. To prove it is enough to see ECMAScript 5 Object.getPrototypeOf
method which of course returns only one value. For older interpreters you could try __proto__
property (non-standard) of simply obj.constructor.prototype
.
The example you've made give you a possibility to have all features from two different prototypes, however it brakes the prototype chain - this is why instanceof
operator returns false for A and B. In fact prototypes of A or B are not prototypes of your object, but the mixin of them which you have made using the extend
function. The function name is very misleading (however such name is used by some of frameworks and libraries) - because we don't extend any object (in object-oriented programming meaning) - we build a mixin of two object - which is completely different design pattern.
Bit out off topic - if you're experimenting with objects and prototypal inheritance - try to play with Object.create
method (of ECMAScript 5). It's very useful in this case.
精彩评论