1

我有以下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 之后:未定义。

为什么在 $.post 的回调函数中,类的属性是未定义的。有人可以帮我吗?非常感谢。

4

5 回答 5

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
于 2011-11-21T07:05:23.690 回答
1

您正在失去上下文,因此this指向不同的对象。jQuery 中有一个内置的代理功能。更改您的代码如下:

// ...
$.ajax({
    url: 'some-url',
    async: true,
    type: 'POST',
    dataType: 'json',
    success: $.proxy(this.callback, this)
});
// ...
于 2011-11-21T07:19:00.757 回答
0

问题是由于函数闭包造成的。回调的“this”不指向“test”,而是指向回调函数本身。

使用这样的东西

function binder (func, thisValue) {
            return function () {
                return func.apply(thisValue, arguments);
            }
        }

var bindedFun = binder(function () {
            alert('after: ' + this.a);
        }, test);
于 2011-11-21T07:07:07.537 回答
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

        });
    };
于 2011-11-21T08:05:33.193 回答
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>
于 2011-11-21T08:09:08.920 回答