Okay, my first attempt at trying to explain what I was doing failed miserably. I'm basically copying Crockford's Object.create(), except with private variables.
If you look at the accepted answer here http://stackoverflow.com/questions/2107556/how-to-inherit-from-a-class-in-javascript, you will see Object.create as the last pattern, which I think better fits the prototypal nature of Javascript (objects beget objects) instead of emulating classical inheritance (classes beget objects).
If you look at Wikipedia's article on prototype based programming (http://en.wikipedia.org/wiki/Prototype-based_programming), you can see more of what I mean.
The drawback with Object.create() though is that there is no support for private members. This is what I propose:
Function.prototype.from = function(obj) {
function F() {this.parent = Object(obj);}
F.prototype = obj;
var out = new F();
this.apply(out);
return out;
};
Then, you create objects as thus:
// Create an object
var a = function() {
var private_property = 'blue';
this.public_property = 7;
this.public_method = function() {
alert(this.public_property + ' ' + private_property);
}
}.from(null); // .from() works too, but .from(null) is more revealing
// Create a new object using 'a' as the prototype
var b = function() {
var private_property = 'red';
this.public_property = 8;
}.from(a);
// See the results
a.public_method(); // Alerts '7 blue'
b.public_method(); // Alerts '8 blue' - Parent methods use parent private variables
a.public_method = function() { alert('rabbit'); };
a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'rabbit'
b.public_method = function() { alert('dog'); };
a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'dog' - Parent method is overwritten
The way I made the "from" function is such that when a parent object changes its methods, if you want to prevent the change in a child instance, you can specify:
this.public_method = this.parent.public_method;
in the child instance.
Note also that objects created ex nihilo do not inherit from Object (hasOwnProperty, etc..). You must explicitly specify this as .from(Object).
Benefits of this pattern:
- Memory is not wasted for each new instance
- It adheres to a true prototypal inheritance pattern
- You have access to the parent object using this.parent (this._proto_ is browser specific)
- Private variables now exist
There is one major drawback of this method that I can think of: the 'function()' syntax may confuse people into thinking a function is assigned to the variable instead of an object.
My question is, are there other drawbacks that I am missing? (Don't include drawbacks of the prototypal pattern--that's subjective--but only of my implementation).