JS / JQ中简单的“丢失$ this”范围问题解释了吗?

时间:2013-01-09 14:45:14

标签: javascript jquery

我正在努力提高我的JS技能,并且我已经将一堆代码重写为命名空间对象文字(我想。)但是现在我有一个“这个”相关的问题。帮帮我理解?

这是缩写代码。

var MYAPP = {

    init: function(){
        $(document).on("click",".showLove", MYAPP.showLove);
    },
    showLove: function(){
         var thisId = MYAPP.findId();
         $.post(//// do AJAXy stuff using thisId);
    },
    findId: function(){
        var thisClass = $(this).attr('class');
        var thisIdPos = thisClass.indexOf("id-")+3;
        var thisId = thisClass.substr(thisIdPos, 3);
        return thisId;
    }
}

所以我相信你可能会看到这个问题。在findId函数$中这是未定义的,我收到一个错误。之前我在showLove中有findId逻辑,一切正常。我将findId逻辑移动到它自己的方法,因为它在几个不同的地方使用。

所以,让我问一下这个 - >为什么$(this)指向'showLove'中的正确元素..但不是'findId'?因为'findId'是从'showLove'内部调用的,所以它不应该访问相同的变量,包括$(this)?这是我的第一个“自我=这个”情况吗?

我知道这是一个基本问题,但如果有人能帮助我理解,我会......呃......'showLove'。

4 个答案:

答案 0 :(得分:1)

如果你想保留这个,你需要做

MYAPP.findId.call(this);

答案 1 :(得分:1)

showLove中的

this来自$(document).on("click",".showLove", MYAPP.showLove);

中的实例化

var thisId = MYAPP.findId(this); //将其传递给函数

findId: function(thisPassed){并以该名称引用它

至少这样做的一种方法。

答案 2 :(得分:1)

您正在将MYAPP.showLove传递给jQuery并说“将此函数作为文档的点击处理程序附加”。

执行此操作时,MYAPP.showLove 忘记它已附加到MYAPP,因为您只传递功能,没有参考到命名空间。

因此,当showLove作为点击处理程序执行时,this不再是MYAPP。通常,当您从对象this分离某个函数时,会变为windowundefined(ES5)。但是,jQuery使用this.showLove决定call()应该是被点击的apply()元素。

但是,当您在MYAPP.findId()中致电showLove时,this仍设为MYAPP;因为findId所附加的是(你在 MYAPP上调用方法)。

要解决此问题(无双关语),您可以将this的值传递给findId(首选,IMO),或使用call() / apply()

var MYAPP = {

    init: function(){
        $(document).on("click",".showLove", MYAPP.showLove);
    },
    showLove: function(){
         var thisId = MYAPP.findId(this);
         $.post(//// do AJAXy stuff using thisId);
    },
    findId: function(which){
        var thisClass = $(which).attr('class');
        var thisIdPos = thisClass.indexOf("id-")+3;
        var thisId = thisClass.substr(thisIdPos, 3);
        return thisId;
    }
}

或:

var MYAPP = {

    init: function(){
        $(document).on("click",".showLove", MYAPP.showLove);
    },
    showLove: function(){
         var thisId = MYAPP.findId().call(this);
         $.post(//// do AJAXy stuff using thisId);
    },
    findId: function(){
        var thisClass = $(this).attr('class');
        var thisIdPos = thisClass.indexOf("id-")+3;
        var thisId = thisClass.substr(thisIdPos, 3);
        return thisId;
    }
}

答案 3 :(得分:1)

我认为问题依赖于你如何调用 findId 函数。无论何时你这样做:

MYAPP.findId()

您静态引用该函数,该函数将在没有对象上下文的情况下执行。如果你想保留这个上下文,你需要像这样调用它:

MYAPP.findId.call(this)

通过这样做,findId中的 this 变量将绑定到您作为参数传递给调用函数的任何对象(在这种情况下,当前,因此你保留这个参考)

旁边:我建议你看一下underscore.js的绑定函数,它是一个非常有用的帮手!