patternjavascriptMinor
Multiple inheritance with JavaScript with support of calling of super() methods
Viewed 0 times
javascriptwithsuperinheritancemethodsmultiplecallingsupport
Problem
I have just finished working on a Node.JS module that provides "multiple inheritance that works". I had some really specific requirements:
The "support for multiple inheritance" was the real sticky one. Multiple inheritance opens a huge can of worms when dealing with JavaScript, which has a linear prototype chain.
My solution to the problem was simple: when inheriting from multiple classes, I actually create a new prototype chain made up of clones of every prototype (even the ones deep in) of the constructor you want to inherit from, avoiding duplication (see the documentation for more info).
This is a method I haven't seen anywhere else (which kind of worries me). I worked on it for the last five days nights (literally) and... well, it all seems to work. UPDATE: I think ringJs does something similar, although its code is a little hard to read
Notes:
-
The implementation of this.inherited() is interesting. Basically, it looks for the function in the prototype chain, and once found it looks up the method starting from that prototype object. I haven't seen this done anywhere else, but it's the only way I can assume ECMA 6 will do this
-
There is a bit of META data: when inheriting from multiple classes, each "cloned" one keeps a link to the original one (in the OriginalConstructor attribute of the constructor itself), in order to make ,
-
The code is on GitHub too -- the code there has a lot of examples that test the thing. I will m
- Works in safe mode
- Auto-calling of parent constructors
- Makes sure that a constructor is only ever in the inheritance chain once
- Support for multiple inheritance
- Copying of class-wide functions over from parent to child
- Ability to run this.inherited(arguments) from a method which would result on calling the method of a parent class
The "support for multiple inheritance" was the real sticky one. Multiple inheritance opens a huge can of worms when dealing with JavaScript, which has a linear prototype chain.
My solution to the problem was simple: when inheriting from multiple classes, I actually create a new prototype chain made up of clones of every prototype (even the ones deep in) of the constructor you want to inherit from, avoiding duplication (see the documentation for more info).
This is a method I haven't seen anywhere else (which kind of worries me). I worked on it for the last five days nights (literally) and... well, it all seems to work. UPDATE: I think ringJs does something similar, although its code is a little hard to read
Notes:
-
The implementation of this.inherited() is interesting. Basically, it looks for the function in the prototype chain, and once found it looks up the method starting from that prototype object. I haven't seen this done anywhere else, but it's the only way I can assume ECMA 6 will do this
-
There is a bit of META data: when inheriting from multiple classes, each "cloned" one keeps a link to the original one (in the OriginalConstructor attribute of the constructor itself), in order to make ,
object.instanceOf() possible ; also, the actual constructor function defined by the user (to initialise values etc.) is stored in the .ActualCtor attribute of the constructor itself.-
The code is on GitHub too -- the code there has a lot of examples that test the thing. I will m
Solution
Let's start with the basics, and work our way up:
-
There are a few problems with your
All of the above were reported by my IDE as soon as I pasted your code. Consider using a linter to ensure high code quality.
A few other things I spot by reading:
Note, I ran out of time, expect more review and answers to your questions
"use NONstrict";What is that?
- You have places where you have
;but it's not needed (after if, after while), and some places where it is needed but it's not there (aftervar = function()statement).
- If an element is the last in the array/object, don't add a
,after it.
-
There are a few problems with your
declare function:FirstConstructoris never used
list,proto,iiandll,ResultClassare declared more than once
MixedClassis an implied global since it was never defined with thevarkeyword.
All of the above were reported by my IDE as soon as I pasted your code. Consider using a linter to ensure high code quality.
A few other things I spot by reading:
- Using
__proto__is dangerous. It's deprecated and should not be used anymore. A better way is to augment to the constructor's prototype.
- To iterate an array, use
arr.forEach(fn)instead of a for loop. Declarative FTW!
if (!something) { something = somethingElse; }can be shortened tosomething = something || somethingElse.
Note, I ran out of time, expect more review and answers to your questions
Context
StackExchange Code Review Q#77185, answer score: 5
Revisions (0)
No revisions yet.