Reputation: 9926
I've a prototype Node
, of which I create several objects.
During the lifetime of these objects, I may need them to become ValueNode
or PropertyNode
. I currently handle this by using a helper for each "subclass", and sharing a commong interface on both helpers. Think of something like a state pattern.
However, I'd like to improve this design, by actually extending the existing objects with the aditional functionality, and not using helpers.
ie:
n = new Node();
...
// n needs to become a ValueNode
// ???
n.methodDefinedForValueNodesOnly();
Is this possible in javascript? And is it "good practice"?
Upvotes: 0
Views: 74
Reputation: 9926
After reading this article on mixins, I ended up using the following solution (which basically uses mixins nicely).
Node = function() {};
Node.prototype.one = function() {alert(1)};
asValueNode = (function() {
function two() {
alert(2)
};
return function() {
this.two = two;
return this;
}
})();
u = new Node();
// u is a usable Node.
// ...
// Make u a ValueNode
asValueNode.call(u);
u.one();
u.two();
Upvotes: 1
Reputation: 9424
In JavaScript you can perform prototype inheritance just once. You can use some framework that provide a rich class subsystem like ExtJS, Ember.js, etc. Another approach could be to iterate over the properties of the desired object and apply then to the target object. Something like this:
function Node( desc ) {
this.desc = desc;
this.doNodeThing = function() {
console.log( "noding for " + this.desc );
}
}
function FooNode( desc ) {
this.desc = desc;
this.doFooNodeThing = function() {
console.log( "foo noding for " + this.desc );
}
}
function BarNode( desc ) {
this.desc = desc;
this.doBarNodeThing = function() {
console.log( "bar noding for " + this.desc );
}
}
function inherit( obj, superObj ) {
for ( var x in superObj ) {
if ( typeof superObj[x] == "function" ) {
obj[x] = superObj[x];
}
}
}
var n1 = new Node( "tree node" );
n1.doNodeThing();
var n2 = new Node( "folder node" );
n2.doNodeThing();
inherit( n1, new BarNode() );
n1.doBarNodeThing();
//n2.doBarNodeThing(); <= TypeError: n2.doBarNodeThing is not a function
inherit( n1, new FooNode() );
n1.doBarNodeThing();
n1.doFooNodeThing();
//n2.doFooNodeThing(); <= TypeError: n2.doFooNodeThing is not a function
The code above will add functions to the object itself, not to its prototype.
jsFiddle: http://jsfiddle.net/davidbuzatto/3cCGC/
Upvotes: 0