In JavaScript, the \"this\" operator can refer to different things under different scenarios.
Typically in a method within a JavaScript \"object\", it refers to the
this
corresponds to the context for the function call. For functions not called as part of an object (no .
operator), this is the global context (window
in web pages). For functions called as object methods (via the . operator), it's the object.
But, you can make it whatever you want. All functions have .call() and .apply() methods that can be used to invoke them with a custom context. So if i set up an object Chile like so:
var Chile = { name: 'booga', stuff: function() { console.log(this.name); } };
...and invoke Chile.stuff(), it'll produce the obvious result:
booga
But if i want, i can take and really screw with it:
Chile.stuff.apply({ name: 'supercalifragilistic' });
This is actually quite useful...
If you're using Prototype you can use bind() and bindAsEventListener() to get around that problem.
You can also use Function.Apply(thisArg, argsArray)... Where thisArg determines the value of this inside your function...the second parameter is an optional arguments array that you can also pass to your function.
If you don't plan on using the second argument, don't pass anything to it. Internet Explorer will throw a TypeError at you if you pass null (or anything that is not an array) to function.apply()'s second argument...
With the example code you gave it would look something like:
YAHOO.util.Connect.asyncRequest(method, uri, callBack.Apply(this));
As soon as callback methods are called from other context I'm usually using something that I'm call callback context:
var ctx = function CallbackContext()
{
_callbackSender
...
}
function DoCallback(_sender, delegate, callbackFunc)
{
ctx = _callbackSender = _sender;
delegate();
}
function TestObject()
{
test = function()
{
DoCallback(otherFunc, callbackHandler);
}
callbackHandler = function()
{
ctx._callbackSender;
//or this = ctx._callbacjHandler;
}
}
If you're using a javascript framework, there may be a handy method for dealing with this. In Prototype, for example, you can call a method and scope it to a particular "this" object:
var myObject = new TestObject();
myObject.firstMethod.bind(myObject);
Note: bind() returns a function, so you can also use it to pre-scope callbacks inside your class:
callBack.bind(this);
http://www.prototypejs.org/api/function/bind
In JavaScript, this
always refers to the object invoking the function that is being executed. So if the function is being used as an event handler, this
will refer to the node that fired the event. But if you have an object and call a function on it like:
myObject.myFunction();
Then this
inside myFunction
will refer to myObject
. Does it make sense?
To get around it you need to use closures. You can change your code as follows:
function TestObject() {
TestObject.prototype.firstMethod = function(){
this.callback();
YAHOO.util.Connect.asyncRequest(method, uri, callBack);
}
var that = this;
TestObject.prototype.callBack = function(o){
that.secondMethod();
}
TestObject.prototype.secondMethod = function() {
alert('test');
}
}