Skip to content

Instantly share code, notes, and snippets.

@colynb
Created August 23, 2012 00:07
Show Gist options
  • Save colynb/3430759 to your computer and use it in GitHub Desktop.
Save colynb/3430759 to your computer and use it in GitHub Desktop.
JavaScript: Namespacing Native Object Prototypes
/*
* Where I work, I thought it would come in handy to have a
* collection of methods that I could apply to native JS
* objects, like strings.
*
* While it would be useful to do this:
*/
String.prototype.touch = function() {
return this + ' has been touched';
}
var myString = 'Touch me!';
console.log(myString.touch()); // outputs "Touch me! has been touched"
/*
* I never liked the idea of polluting that global object space like that.
* Therefore, I've come up with a way to have namespaced methods on the objects I was to extend.
*
*/
/*
* In theory, I was expecting to be able to do something like this:
*/
String.prototype.MY_NAMESPACE = {
touch: function() {
return this + ' has been touched';
}
}
var myString = 'Touch me!';
console.log(myString.MY_NAMESPACE.touch());
/*
* A good JavaScript developer could see what's wrong with this immediately (did you catch that? wink wink).
* While it won't give you an error, it will not give you the expected result.
* The above code outputs something like: "[object Object] has been touched"
*
* The problem is that because what I'm trying to do is happening in context of an object that's not the string.
* The 'this' variable no longer refers to the String object, it refers to the 'MY_NAMESPACE' object.
*
* So, how can I retain the context of the String object?
*
* I decided that the only way to do that is to return a function to the prototype instead of an object.
*
* Like this:
*/
String.prototype.MY_NAMESPACE = function() {
var obj = this;
var touch = function() {
return obj + ' has been touched!';
}
return {
touch: touch
}
}
var myString = 'Touch me!';
console.log(myString.MY_NAMESPACE().touch());
/*
* If you notice, now I have to refer to my namespace as a function that returns the method I want "MY_NAMESPACE().touch()"
* It's not as pretty, but it works.
* The reason it works is because in the function I now have the ability to remember the original context, by saving
* the 'this' variable to the 'obj' variable. Then I use 'obj' instead when referring to the string.
*/
/*
* If anybody knows of a better solution, preferably one that allows me to use an object namespace as opposed to a
* function namespace, let me know. Of course, if you see any glaring errors, memory leaks, or just think I'm a really
* terrible programmer, don't hesitate to hate on me. The quicker the better.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment