views:

71

answers:

1

Trying to grasp Prototyping in Javascript. Trying to create my own namespace to extend the String object in JavaScript.

Here is what I have so far (a snippet):

var ns {
 alert: function() {
  alert (this);
 }
}
String.prototype.$ns = ns;

As you can see, I am trying to place what will be a series of functions into the ns namespace. So I can execute a command like this:

"hello world".$ns.alert();

But the problem is, the this doesn't reference the text being sent (in this case, "hello world"). What I get is an alert box with the following:

[object Object]

Not having a full grasp of the object-oriented nature of JavaScript, I am at a loss, but I am guessing I am missing something simple.

Does anyone know how to achieve this (get the source text from the nested object)? Short of that, I am left with having to do procedural programming ( ns.alert("hello world"); ) which I am trying to avoid.

Thanks -

+5  A: 

This is happening because when you invoke a reference, its base object is set as the this value of the invoked method (more technical details here).

So when you invoke "hello world".$ns.alert(); the this value inside your alert method, will refer to "hello world".$ns, which is String.prototype.$ns.

I don't think adding object levels (namespaces) inside the prototype of built-in objects can be useful, I usually recommend to not modify objects you don't own.

CMS
I think it would be useful (to me, anyway). Is there any way to do what I am trying to do (perhaps something like this.parent or this.caller or something like that?)Thanks -
OneNerd
@OneNerd, well being `$ns` an object, there is no way to know from where the previous reference comes, a solution (if you *really* need this), would be to make `$ns` a function to preserve the context where it was called (the string) and return an object containing the methods (something like [this](http://jsbin.com/iwiku/edit)), but *I don't really like it*, IMO there is nothing better than just calling `ns.alert("Hello World");`, I'm not sure why you are trying to avoid the more unobtrusive/simple approach.
CMS
well, your solution definitely works, although I don't care for having to do the "hello".ns().alert(); (the () after ns). Maybe I should go your route instead. My goal was to add some utility functions to objects and avoid any naming collisions (by placing my stuff inside a namespace). I guess I will have to decide if your proposed way (which seems to be the only way) is going to be a good idea (sounds like you dont think so, so I will have to roll it around in my head). Thanks though -- will mark yours as accepted answer.
OneNerd