Last active
December 16, 2015 22:28
-
-
Save madbook/5506730 to your computer and use it in GitHub Desktop.
Simple constructor function for creating tree-like object structures. Useful if you need simple inheritance on a tree-like data structure.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* every NodeObject's prototype is another NodeObject. The lowest level | |
* NodeObject's prototype is the NodeObject prototype. | |
* | |
* Each NodeObject has two default properties | |
* {NodeObject} parent : reference to the NodeObject that created this, also | |
* will be this NodeObject's prototype | |
* {NodeObjects[]} childNodes : every node created from this node using the | |
* create method will be added to this array | |
* | |
* these properties are non-enumerable, so the resulting objects are safe | |
* to enumerate over in for loops | |
*/ | |
function NodeObject (attributeList) { | |
var node = Object.create(this, { | |
parent: { value: this }, | |
childNodes: { value: [] } | |
}); | |
var key; | |
if (attributeList instanceof Object) | |
for (key in attributeList) node[key] = attributeList[key]; | |
return node; | |
} | |
// create a child node. The node that calls this method will be the new | |
// node's prototype | |
Object.defineProperty(NodeObject.prototype, 'create', { | |
value: function (attributeList) { | |
var child = NodeObject.call(this, attributeList) | |
this.childNodes.push(child); | |
return child; | |
} | |
}); | |
// creates a new root node. Its necessary to call the NodeObject | |
// constructor this way for a root-level node, so that it's prototype is | |
// the NodeObject prototype and not the window | |
NodeObject.createRoot = function (attributeList) { | |
return NodeObject.call(NodeObject.prototype, attributeList); | |
}; |
Example: setting up a chain where foo inherits from bar, which inherits from bat
compare the standard way, using Object.create
var foo = { fooProp: 'this is a foo' };
var bar = Object.create(foo);
bar.barProp = 'this is a bar';
var bat = Object.create(foo);
bat.batProp = 'this is a bat';
Its not terrible (especially if you know how its done without Object.create),
but its not great either. We can't define the bar and bat objects using
object literal syntax anymore. Furthermore, we have no way of navigating the
inheritance chain (ie, from the foo object, get the bar or bat objects);
Now, see it my way
var foo = NodeObject.create({ fooProp: 'this is a foo' });
foo.create({ barProp: 'this is a bar' });
foo.create({ batProp: 'this is a bat' });
less lines, consistent definition syntax, and we can go from foo->bar and from
bar->foo using the parent/childNodes properties.
FYI you have a typo in your second example:
var bat = Object.create(bat);
Should be
var bat = Object.create(foo);
fixed, thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
example usage, this...
...is roughly equivalent to...
...but with the added benefit of this working