我有以下js片段:
<script language="javascript">
function test() {
this.a = 10;
};
test.prototype.next = function () {
alert('before: ' + this.a);
$.ajax({
url: 'some-url',
async: true,
type: 'POST',
dataType: 'json',
success: this.callback
});
};
test.prototype.callback = function () {
alert('after: ' + this.a);
};
$(document).ready(function () {
var test1 = new test();
test1.next();
});
</script>
总是产生结果: 之前:10 之后:undefine。
为什么在$ .post的回调函数中,类的属性是未定义的。谁能帮助我?非常感谢。
答案 0 :(得分:7)
success: this.callback
这不起作用。您需要将回调绑定到实例(this
)。否则它将失去其范围。遗憾的是,单独的功能不会记住它。
手动方式是
var me = this;
// .....
success: function(x,y,z) { me.callback(x,y,z) }
我找不到jQuery现在拥有的内置帮助器。在CoffeeScript中,您只需使用胖箭=>
。
更新:找到了jQuery方式:您可以为context
指定一个参数$.ajax
,对于所有回调,该参数将变为this
:
success: this.callback,
context: this
答案 1 :(得分:1)
您正在丢失上下文,因此this
指向不同的对象。 jQuery中有一个内置代理函数。按如下方式更改您的代码:
// ...
$.ajax({
url: 'some-url',
async: true,
type: 'POST',
dataType: 'json',
success: $.proxy(this.callback, this)
});
// ...
答案 2 :(得分:0)
问题是由于函数关闭。用于回调的“this”不指向“test”,而是指向回调函数本身。
使用类似的东西
function binder (func, thisValue) {
return function () {
return func.apply(thisValue, arguments);
}
}
var bindedFun = binder(function () {
alert('after: ' + this.a);
}, test);
答案 3 :(得分:0)
另一种方法是使回调成为可以访问本地范围的本地函数,并在本地范围内保存对this
的引用。我认为这可以正常工作,因为回调可能需要访问this
,但它不一定是一种方法来执行此操作。
test.prototype.next = function () {
var self = this;
function callback() {
alert('after: ' + self.a);
}
alert('before: ' + this.a);
$.ajax({
url: 'some-url',
async: true,
type: 'POST',
dataType: 'json',
success: callback
});
};
答案 4 :(得分:0)
您的代码中的一些更改(如下所示)
<script language="javascript">
function test() {
this.a = 10;
};
test.prototype.next = function () {
alert('before: ' + this.a);
var oThis = this; //Save refernce of Test() function in a varaiable. then use it
$.ajax({
url: 'some-url',
async: true,
type: 'POST',
dataType: 'json',
success: oThis.callback // This is change this=> earlier was referring
//$.ajax object so save this of test()
// in a variable and then use it
});
};
test.prototype.callback = function () {
alert('after: ' + this.a);
};
$(document).ready(function () {
var test1 = new test();
test1.next();
});
</script>