如何正确使用Javascript'this'在我的情况下?

时间:2011-08-26 15:22:23

标签: javascript jquery this

我有以下(简化)代码:

var myModule = {

    submitDummyForm: function(){ 
        console.log(this); // the right object is logged out
        var that = this; // keep a reference
        $.ajax({
            type:'POST',
            url: 'http://localhost/',
            data: {dummyData: 'something'},
            dataType: 'json',
            success: that.dummyFormSuccess

        });
    },

    dummyFormSuccess: function(data){ 
        console.log(this); // 'this' is logged out as some foreign object, most probably jQuery.ajax object
    }
}

导致'this'在dummyFormSuccess中丢失,无论我使用this.dummyFormSuccess还是that.dummyFormSuccessfor作为我的ajaxSubmitForm()的参数。

但是下面的代码会根据需要执行:

var myModule = {

    submitDummyForm: function(){ 
        console.log(this); // the right object is logged out
        var that = this; // keep a reference
        $.ajax({
            type:'POST',
            url: 'http://localhost/',
            data: {dummyData: 'something'},
            dataType: 'json',
            success: function(data) {
                 that.dummyFormSuccess(data);
            }
        });
    },

    dummyFormSuccess: function(data){ 
       console.log(this); // now 'this' is logged out correctly as the real myModule object
    }
}

我对Javascript的高级主题仍然不太满意,但我已经知道,“这个”可能会被重新定义,具体取决于它的使用位置。我想如果我使用'that'来存储对'this'的引用,它也应该将我的'this'保留在被调用的函数中。看起来很奇怪,我可以在环绕函数中调用that.dummyFormSuccess(data)并且它在内部得到正确的'this',但是如果我只是将它分配给$ .ajax成功,我的'this'就会丢失。

任何人都可以解释一下,在我的情况下,'这个'会丢失在哪里以及为什么它在第二个例子中正常工作?这是jQuery的问题(​​也许jQuery.ajax()在我的情况下以某种方式覆盖了我的'this')或者只是该语言的一个特性?

4 个答案:

答案 0 :(得分:1)

你误解了this

this参数的值由 callsite 决定 - 调用您的函数的代码。
当您通过that.dummyFormSuccessthis.dummyFormSuccess时,您只是传递了一个恰好来自您对象的函数。
thisthat对象仅用于检索函数实例;它没有与功能捆绑在一起。

当jQuery调用你的回调时,它总是在jqXHR对象的上下文中调用它 传递function(data) { that.dummyFormSuccess(data); }时,将在此jqXHR对象的上下文中调用函数表达式 但是,您的回调会在dummyFormSuccess的上下文中调用that,因此其this就是您想要的。

答案 1 :(得分:1)

一切都是正确的。您的this在第一个示例中丢失,因为您函数that.dummyFormSuccess分配给jQuery ajax对象的success。所以,这样,在jQuery内部,它被称为类似ajax.success的东西。因此,this会被ajax对象覆盖。

使用第二种方法,您可以创建一个匿名函数并将其分配给success。因此,在您的匿名函数中,this指向ajax对象,但that变量可以访问且尚未被覆盖。

答案 2 :(得分:1)

您可以将JavaScript中的'this'视为函数参数列表中的附加参数。 因此,每次调用函数都会在this参数中包含自己的值。以下是在JS

中调用函数的三种方法
  • foo(); - 函数this内部将设置为默认值 命名空间对象(浏览器环境中的窗口)。

  • obj.foo(); - this将在foo()中获得obj引用。

  • foo.call(obj); - 将this设置为obj(与上述相同),即会调用'foo'

答案 3 :(得分:0)

由于函数也可以表示对象(并且它是对象),this表示该函数。 (不同的范围)

您需要做的是将var that = this;置于dummyForm : function之外(其上方的行),然后执行console.log(that)

var that = this;
dummyFormSuccess: function(data){ 
   console.log(that); // now 'this' is logged out correctly as the real myModule object
}