Multiple prototypical inheritance in Javascript -


i have 2 base classes, parentclass1 , parentclass2. want multiple prototypical inheritance childclass.

with single parent class, had code follows.

var parentclass = function() {    };    parentclass.prototype.greetuser = function(name) {      console.log('hi. hello,', name);  };    var childclass = function(name) {    this.greetuser(name);  };    childclass.prototype = object.create(parentclass.prototype);    var obj = new childclass('john');  // hi. hello, john


and when have inherit 2 parent classes, tried following code.

var parentclass1 = function() {    };    parentclass1.prototype.greetuser = function(name) {      console.log('hi. hello,', name);  };    var parentclass2 = function() {    };    parentclass2.prototype.askuser = function(name) {      console.log('hey, how you,', name);  };    var childclass = function(name) {    this.askuser(name);    this.greetuser(name);  };    childclass.prototype = object.create(parentclass1.prototype);  childclass.prototype = object.create(parentclass2.prototype);    var obj = new childclass('john');  // error.

but seems like, accept last mentioned object.create() .

so later, tried switching second object.create() object.assign(), works fine.

childclass.prototype = object.create(parentclass1.prototype); childclass.prototype = object.assign(childclass.prototype, parentclass2.prototype); 

but concern object.assign() doing a clone. right way it? or there better alternatives?

sorry making question, lengthy. in advance.

note: had brief this , this

it not useful 2 assignments prototype property, last 1 overwrite first. can this, since object.assign accepts more arguments:

object.assign(childclass.prototype, parentclass1.prototype, parentclass2.prototype); 

note object.assign performs shallow copy. copy has made sure: need prototype object different both other prototypes: union of both. inevitably need somehow copy members of parent prototypes target prototype object.

some caveats:

1. object.assign makes shallow copy

since object.assign performs shallow copy, might cases interfere parent prototype. might want or not want.

example:

var parentclass1 = function() {    };    parentclass1.prototype.userlist = [];  parentclass1.prototype.adduser = function(name) {      this.userlist.push(name);  };    var parentclass2 = function() {    };    parentclass2.prototype.askuser = function(name) {      console.log('hey, how you,', name);  };    var childclass = function(name) {    this.askuser(name);  };    object.assign(childclass.prototype, parentclass1.prototype, parentclass2.prototype);    var p = new parentclass1('parent');  var obj = new childclass('john');  obj.adduser('tim'); // added child,  console.log(p.userlist); // parent has tim...

2. object.assign copies enumerable properties

this means in cases not properties had hoped for. wanted inherit array.prototype, want child object have length property, since not enumerable, not object.assign:

var parentclass2 = function() {    };    parentclass2.prototype.askuser = function(name) {      console.log('hey, how you,', name);  };    var childclass = function(name) {    this.askuser(name);  };    object.assign(childclass.prototype, array.prototype, parentclass2.prototype);    var obj = new childclass('john');  console.log(obj.length); // undefined  console.log(array.prototype.length); // 0

3. object.assign executes getters

object.assign cannot copy getters. instead executes them retrieve value copy. executing code on parent prototype may have effects (by design of getter) on state of parent prototype. might undesired behaviour in context of copy.

secondly, value of getter can result of calculation , state of object, returning different values each time referenced. object.assign reference once, , create property has single value. see effect in example:

var parentclass1 = function() {    };    // define getter on prototype returns  // random number between 0 , 999, every time referenced:  object.defineproperty(parentclass1.prototype, 'randomnumber', {       get: function() {          return math.round(math.random() * 1000);       },       enumerable: true   });    var parentclass2 = function() {};    parentclass2.prototype.askuser = function(name) {      console.log('hey, how you,', name);  };    var childclass = function(name) {    this.askuser(name);  };    object.assign(childclass.prototype, parentclass1.prototype, parentclass2.prototype);    var p = new parentclass1('parent');  var obj = new childclass('john');  console.log('different:');  console.log(p.randomnumber);  console.log(p.randomnumber);  console.log(p.randomnumber);  console.log('always same:');  console.log(obj.randomnumber);  console.log(obj.randomnumber);  console.log(obj.randomnumber);
.as-console-wrapper { max-height: 100% !important; top: 0; }

further reading

the concept of combining multiple prototypes new 1 coined "mixin". here related q&a:

see factory composition.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -