Consider the following code:
function Dog()
{
this.foo = function() {};
this.walk = function()
{
if(canWalk())
{
alert('walking');
return;
}
alert('I have no legs!');
}
canWalk = function()
{
this.foo();
return false;
}
}
var instance = new Dog();
instance.walk();
There is a bug in that code with the “privileged” canWalk() method assuming the this pointer points to the instance of Dog. It actually appears to be pointing to the global object which is confusing me! I’ve read that due to closures I can grab a reference to this in the scope of the constructor then use that reference in my “privileged” method but that seems like a hack.
I just barely grasp the behavior of the this pointer in various contexts. I understand that a method that is “attached” to an object will receive a this pointing to the attached object. For example, foo.doStuff() would have a this pointing to the foo instance.
What’s troubling is that while I think I’m being clever and creating “privileged” methods on my OBJECT, it appears that I’m ACTUALLY dumping functions into global scope! Perhaps there was a global method called init() (quite possible) from another library or file not my own creation. If I then defined a nice little encapsulated object with a “privileged” method called init() I would be replacing the other global init() method.
My question is, what is the best practice for creating “privileged” methods (and fields for that matter) that are scoped to the object they are intended to belong to? What other approach to my sample object would provide private or privileged methods while also being properly scoped. I’m not looking for obscure solutions that meet the requirements but rather what the best practice is.
Don’t use
this. Putvar self = this;at the top of your Dog function and useself. That way you will always have a ‘safe’ reference to the Dog.In your example
thisshould point to theDogthough unless I’m missing something as well.As for your privileged method, you forgot to define the variable. Add
var canWalk;There is another way: closures. I will give an example:
Now you don’t need
thisornew. Additionally you could do this:So you can have references to the
dogin your priveledges functions. I would advise the closure approach if you’re not going to be using prototyping.By the way. To avoid confusion:
and
Are equivalent. The latter can be useful if you have a circular reference between two functions and you want to enforce define-before-use.