TL;DR? Why can\'t I overwrite a constructor\'s prototype from within the constructor?
I\'m figuring out my pattern for prototypica
Why can't I overwrite a constructor's prototype from within the constructor?
It's because constructors are actually called after your object has already been instantiated. And since your object has managed to instantiate before your constructor has touched anything, your constructor has also already been assigned a "default" prototype.
Adding properties to this.constructor.prototype
seems to work -- because you're actually manipulating the constructor's pre-assigned default prototype object, which all of your instances inherit from.
In my examples, this.constructor.prototype
ended up referring to the default-assigned prototype of the constructor: so wholly overwriting it meant all new instances from that moment onward would have that new prototype -- as Bergi said, "too late" -- your current instance would not have that new prototype, as it still has the old default-assigned prototype because it's already been instantiated.
I've come to understand, that the techniques presented in my question simply won't do. The question itself is generally misguided. By combining Bergi's wisdom with my own personal biases, I've come up with this pattern as a means to avoid having to find an answer to the original question altogether:
function extend(p){
return { to: function(C){ for (k in p) if (p.hasOwnProperty(k))
C.prototype[k]=p[k]; return C; } };
};
var orifice = new function Orifice(){
this.exhaust=function(){};
this.ingest=function(){};
};
var Sphincter = extend(orifice).to(function Sphincter(){
this.relax=function(){};
this.tighten=function(){};
});
Here's the extend function, expanded:
function extend(parentObject){
return {
to: function(ChildConstructor){
for (key in parentObject)
if (parentObject.hasOwnProperty(key))
ChildConstructor.prototype[key] = parentObject[key];
return ChildConstructor;
}
};
};
I used this to test that it works:
// TESTING
var s=new Sphincter();
var tests=['relax','tighten','exhaust','ingest'];
for (var i in tests) console.log("s."+tests[i]+"() is "+(tests[i]in s?"present :)":"MISSING!"));
Why can't I overwrite a constructor's prototype from within the constructor?
You can, but it's too late. The new instance has already been generated, inheriting from the old prototype. Maybe read how new works.
I don't like how prototypes are usually defined externally from a constructor.
That's just the way it is. You really should not setup the prototype from within the constructor - it would be executed everytime a new instance is created. That's specifically what prototypes are not supposed to be. See also Assigning prototype methods *inside* the constructor function - why not?
and want to logically encapsulate things better.
You might want to have a look at the various (revealing) module patterns. Or maybe even at some Class
framework.
I'm currently looking for more concrete reasons that I should not go forth with the pattern I've been presenting.
It does not work in Internet Explorer. It would not work in any ES5-compliant environment that does not support the __proto__
property. You should never use it set a prototype on an existing object. Instead, use Object.create (or its shim) for Correct javascript inheritance - which requires that you overwrite the prototype outside of the constructor.
My suggestion is to call your extend
helper outside the constructor on it, which still has a nice syntax.