我在javascript对象中进行了一些Ajax调用。:
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
}
}
}
};
在onreadystatechange函数中,这不再引用主对象,所以我无法访问this.foo。我可以在XMLHttpRequest事件中保留对主对象的引用吗?
答案 0 :(得分:7)
最简单的方法通常是将this
的值存储在局部变量上:
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
}
}
};
}
};
我还怀疑您的myObject
标识符确实是constructor function(您正在分配prototype
属性)。
如果是这种情况,请不要忘记包含正确的constructor
属性(因为您要替换整个prototype
),这只是对构造函数的引用。
可能偏离此问题,但建议阅读:
答案 1 :(得分:5)
另一个简单的解决方案是将onreadystatechange函数绑定到此。 bind
- 该函数与CMS的答案基本相同(即将值添加到闭包中),但bind
以透明方式执行:您继续使用{{1}而不是设置this
变量。
如果您的代码库不包含一个instance
,那么这是一个Function#bind
实现:
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));
};
}
以下是您在代码中使用它的方法:
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
}
};