Monday, February 4th, 2008
Namespaced made easy with Prototype
kangax keeps up his "Prototype by example"-ness by showing a use of Enumerable#inject.
He shows us namespacing made easy:
-
-
String.prototype.namespace = function(separator) {
-
this.split(separator || '.').inject(window, function(parent, child) {
-
return parent[child] = { };
-
});
-
}
-
And then you can use it via:
-
-
// Default separator is '.'
-
'foo.bar.baz.quux'.namespace();
-
-
foo.bar.baz.quux = 'Nothing special...'; // => "Nothing special..."
-
-
// Or using a custom one
-
'MY_AWESOME_APPLICATION::util::DOM::dimensions'.namespace('::');
-
-
'dimensions' in MY_AWESOME_APPLICATION.util.DOM; // => true
-












Alternatively for those not using Prototype – since namespaces are definitely worth using:
String.prototype.namespace = function(separator) {var ns = this.split(separator || '.'), p = window;
for (i = 0; i
Doh – code got cut off:
String.prototype.namespace = function(separator) {var ns = this.split(separator || '.'), p = window;
for (i = 0; i < ns.length; i++) {
p = p[ns[i]] = {};
}
};
We should check if an object is already exist in our namespace chain.
This wont work:
"foo.bar.baz".namespace();
"foo.bar.bay".namespace();
console.log(foo.bar.baz); // undefined
Fixed code:
String.prototype.namespace = function(separator){
this.split(separator || '.').inject(window, function(parent, child) {
var o = parent[child] = parent[child] || { }; return o;
})
}
Awesome snippet. I need to use inject() more often.
Here is a pastied cleaner version of the code fix for the bug Aemkei pointed out: http://pastie.caboo.se/147274
Alternately this version http://pastie.caboo.se/147291 allows for extending exisitng object namespaces as well as setting a custom separator.
It’s a great technique, but it SO doesn’t belong in the String class! Have a function like Namespace.create(’foo.bar.baz.quux’) that does the same thing and returns a reference to the innermost namespace created.
var Namespace = {
separator: ".",
create: function(space){
return space.split(
Namespace.separator
).inject(
window, function(parent, child) {
return parent[child] = parent[child] || {};
})
}
};