无法在JavaScript中使用“类”方法进行回调

时间:2010-10-25 20:15:11

标签: javascript ajax prototype callback

我正忙着用JavaScript包围原型。

以前我在调用这样的东西时遇到了麻烦:

o = new MyClass();
setTimeout(o.method, 500);

我被告知可以通过使用:

来解决它
setTimeout(function() { o.method(); }, 500);

这很有效。我现在遇到了一个不同的问题,我想我可以用同样的方式解决它,只需要放入一个匿名函数。我的新问题是:

MyClass.prototype.open = function() {
    $.ajax({
        /*...*/
        success: this.some_callback,
    });
}

MyClass.prototype.some_callback(data) {
    console.log("received data! " + data);
    this.open();
}

我发现在MyClass.prototype.some_callback的正文中this关键字没有引用调用该方法的MyClass实例,而是看起来是什么jQuery ajax请求(它是一个包含xhr对象的对象以及我的ajax调用的所有参数,等等)。

我试过这样做:

$.ajax({
    /* ... */
    success: function() { this.some_callback(); },
});

但我收到错误:
Uncaught TypeError: Object #<an Object> has no method 'handle_response'

我不确定如何正确地做到这一点。我是JavaScript的新手和原型的概念 - 有时类似行为的类 - 但通常不会让我感到困惑。

那么这样做的正确方法是什么?我是否试图强制JavaScript进入一个不属于它的范例?

2 个答案:

答案 0 :(得分:15)

  

我是否试图强制JavaScript进入一个不属于它的范例?

当你谈论类是的时候。

  

那么这样做的正确方法是什么?

首先,您应该了解this关键字可以包含哪种值。

  1. 简单的函数调用

    myFunc(); - this将引用全局对象(又名window)[1]

  2. 函数调用作为对象的属性(又名方法)

    obj.method(); - this会引用obj

  3. 与新操作员一起调用函数

    new MyFunc(); - this将引用正在创建的new instance

  4. 现在让我们看看它如何适用于您的案例:

    MyClass.prototype.open = function() {
        $.ajax({ // <-- an object literal starts here
            //...
            success: this.some_callback,  // <- this will refer to that object
        });      // <- object ends here
    }
    

    如果要调用当前实例的some_callback方法,则应保存对该实例的引用(对于一个简单变量)。

    MyClass.prototype.open = function() {
        var self = this; // <- save reference to the current instance of MyClass
        $.ajax({ 
            //...
            success: function () {
                self.some_callback();  // <- use the saved reference
            }                          //    to access instance.some_callback
        });                             
    }
    

    [1]请注意,在新版本(ES 5 Str。)中,案例1会导致this成为值undefined

    [2]还有一种情况是您使用callapply来调用具有给定this的函数

答案 1 :(得分:1)

在@gblazex的响应的基础上,我对用作回调的源和目标的方法使用以下变体:

className.prototype.methodName = function(_callback, ...) {

    var self = (this.hasOwnProperty('instance_name'))?this.instance_name:this;

    if (_callback === true) {

        // code to be executed on callback

    } else {

        // code to set up callback
    
    }

};

在初始调用中,“ this”是指对象实例。在回调中,“ this”是指您的根文档,要求您引用根文档的实例属性(instance_name)。