Javascript Inheritance And Hoisting
Solution 1:
For multi-link prototype chains, if the statements are out of order, the chain fails to connect properly.
Yes. You need to set Type.prototype
before using it to create ChildType.prototype
. This doesn't have to do anything with the hoisting of the function declarations.
Is there a way to implement inheritance in JavaScript that "works" regardless of the order in which my files are concatenated?
Well, you can might use Object.setPrototypeOf
:
functionChildType(){
Type.call(this);
}
Object.setPrototypeOf(ChildType.prototype, Type.prototype);
functionType(){
ParentType.call(this);
}
Object.setPrototypeOf(Type.prototype, ParentType.prototype);
functionParentType(){
this.data = "";
}
However, you really really want to avoid that method, and relying on hoisting like this is a very bad practice, so you really should fix your concatenation script to use the correct order. Or use a module system that figures dependencies out for you.
My first though was the
class
andextends
way of doing things, but then I learned that evenclass
definitions aren't hoisted!
That's a good thing. Just consider them to be purely sugar - you always need to set them up in the correct order, following the hierarchy.
Solution 2:
The functions are hoisted, so they can be out of order, but the calls to chain the prototypes must be in order.
If they are out of order, your code will look like the following after hosting.
functionParentType(){
this.data = "";
}
functionType(){
ParentType.call(this);
}
functionChildType(){
Type.call(this);
}
ChildType.prototype = Object.create( Type.prototype );
ChildType.prototype.constructor = ChildType;
Type.prototype = Object.create( ParentType.prototype );
Type.prototype.constructor = Type;
That is, you chain ChildType.prototype
toType.prototype
and then you overwrite Type.prototype
to chain it to ParentType.prototype
.
There is no way to make this work out of order, JavaScript inheritance depends on those lines of code being called in order.
Solution 3:
One way to do it is to declare a static initializer for each type.
However, this is only possible at execution runtime (via Object.crate
or via assignment) and therefore we are back at start. If your files are really concatenated in random order, then you should use more complex mechanisms with a sort of "factory" function that will create the types as they appear and put subtypes "on hold" until their parent is created.
Simplified example just for illustration purposes:
functionfactory(precondition, callback)
{
if( !this.registry ) this.registy = [];
if( !precondition || this.registry[precondition] )
this.registry[callback()] = true;
elsesetTimeout(function(){factory(precondition, callback);}, 100);
}
factory('Type', function()
{
Window.ChildType = function(){}
return'ChildType';
});
factory(null, function()
{
Window.Type= function(){}
return'Type';
});
Post a Comment for "Javascript Inheritance And Hoisting"