开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜