Created
August 23, 2012 00:07
-
-
Save colynb/3430759 to your computer and use it in GitHub Desktop.
JavaScript: Namespacing Native Object Prototypes
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
/* | |
* 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