I make some Ajax calls from inside a javascript object.:
myObject.prototye = {
ajax: function() {
this.foo = 1;
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
开发者_开发百科if(req.status == 200) {
alert(this.foo); // reference to this is lost
}
}
}
};
Inside the onreadystatechange function, this does not refer to the main object anymore, so I don't have access to this.foo. Ho can I keep the reference to the main object inside XMLHttpRequest events?
The most simple approach is usually to store the value of this
on a local variable:
myObject.prototype = {
ajax: function (url) { // (url argument missing ?)
var instance = this; // <-- store reference to the `this` value
this.foo = 1;
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if (req.status == 200) {
alert(instance.foo); // <-- use the reference
}
}
};
}
};
I suspect also that your myObject
identifier is really a constructor function (you are assigning a prototype
property).
If that's the case don't forget to include the right constructor
property (since you are replacing the entire prototype
), which is simply a reference back to the constructor.
Maybe off-topic to this issue but recommended to read:
- Constructors considered mildly confusing
An other simple solution is to bind your onreadystatechange function to this. bind
-ing the function does essentially the same thing as in CMS's answer (that is, adding the value to the closure), but bind
does it in a transparent way: you keep using this
instead of setting a instance
variable.
Here is a Function#bind
implementation if your code base doesn't include one :
Function.prototype.bind = function(obj) {
var __method = this;
var args = []; for(var i=1; i<arguments.length; i++) args.push(arguments[i]);
return function() {
var args2 = []; for(var i=0; i<arguments.length; i++) args2.push(arguments[i]);
return __method.apply(obj, args.concat(args2));
};
}
And here is how you can use it in your code :
myObject.prototype = {
ajax: function() {
this.foo = 1;
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200) {
alert(this.foo); // reference to this is *kept*
}
}
}.bind(this) // <- only change
}
};
精彩评论