In my current web project, I'm working with multiple JavaScript files, each containing type definitions that inherit from other types. So in any given file, I could have something like ...
function Type(){
ParentType.call(this);
}
Type.prototype = Object.create( ParentType.prototype );
Type.prototype.constructor = Type;
... with the ParentType
declared similarly in another file:
function ParentType(){
this.data = "";
}
Since working with many JavaScript files becomes bothersome in the <head>
tag, I wrote a bash script to concatenate the files into a single file (called master.js
). That way, I can link a single file in my HTML.
For types that have only a single child, the prototype chain is built correctly, regardless of the order of concatenation of my files. In other words, this snippet ...
function ParentType(){
this.data = "";
}
function Type(){
ParentType.call(this);
}
Type.prototype = Object.create( ParentType.prototype );
Type.prototype.constructor = Type;
... acts identical to this snippet:
function Type(){
ParentType.call(this);
}
Type.prototype = Object.create( ParentType.prototype );
Type.prototype.constructor = Type;
function ParentType(){
this.data = "";
}
When I create an instance of Type
in either scenario, ParentType.prototype.isPrototypeOf(typeobj)
returns true (where typeobj
is my instance of Type
).
However, when I add another type to the end of the "prototype chain", it only works when the files are concatenated in order, i.e.:
function ParentType(){
this.data = "";
}
function Type(){
ParentType.call(this);
}
Type.prototype = Object.create( ParentType.prototype );
Type.prototype.constructor = Type;
function ChildType(){
Type.call(this);
}
ChildType.prototype = Object.create( Type.prototype );
ChildType.prototype.constructor = ChildType;
... and otherwise, the chain "breaks". My guess as to why this is okay in a single-child scenario is because both type definitions get hoisted, and there is only one set of statements to worry about regarding the prototype chain. But for multi-link prototype chains, if the statements are out of order, the chain fails to connect properly.
So what I'm really asking is, is there a way to implement inheritance in JavaScript that "works" regardless of the order in which my files are concatenated? My first though was the class
and extends
way of doing things, but then I learned that even class
definitions aren't hoisted!
Note: by "works", all I mean is that subtypes inherit functions/values from (all of) their parents, and isPrototypeOf
returns true for any object when checked against any of its parents' prototypes.