从另一个函数到达$ this

时间:2012-09-05 20:05:01

标签: javascript jquery

我在我的javascript文件中有这些行,它运行正常。

handleInput = function(e) {
    var $this = $(this),
    id = $this.attr("id");
    alert(id);
}

....

something.bind("keyup", handleInput);

然后我决定延迟输入功能并添加以下行:

handleDelayedInput = function(e) {
    setTimeout(handleInput(e), 50);
}

.....

something.bind("keyup", handleDelayedInput);

但现在alert(id);表示未定义,因为我认为我无法将其传递给该函数。

我是对的吗?我该怎么办?有没有更好的方法呢?

4 个答案:

答案 0 :(得分:2)

这是因为您不再像从jQuery绑定方法调用它时那样传递handleInput任何对象上下文。就个人而言,我会改写这样的事情:

something.on("keyup", function(e) {
    var obj = $(this);
    setTimeout(function(obj) {
        alert(obj.attr("id");
    }, 50);
});

请注意使用on()代替bind(),现在是首选用途。

答案 1 :(得分:1)

使用apply function

var handleDelayedInput = function(e) {
    var that = this;
    setTimeout(function() {
        handleInput.apply(that, [e]);
    }, 50);
}

something.bind("keyup", handleDelayedInput); // Assuming something is a 
                                             // jQuery object

这是working jsFiddle

调用handleInput这样的setTimeout(handleInput(e), 50);会失去上下文,因此在这种情况下,this将不会是您在handleInput内所期望的。

此外,setTimeout应该传递一个函数,而不是函数的结果(除非结果本身就是一个函数)。

答案 2 :(得分:1)

当jQuery调用事件处理程序时,它设置处理函数的上下文。在第二段代码中调用handleInput时不会出现这种情况,因此this设置为默认值window

您可以使用applycall设置上下文:

handleInput.call(this, e);

两者之间的区别在于apply接受一组参数,而您可以逐个将参数传递给callfunc.apply(context, arg1, arg2)

所以你的完整代码是:

handleInput = function(e) {
    var $this = $(this),
    id = $this.attr("id");
    alert(id);
}

handleDelayedInput = function(e) {
    var element = this;
    setTimeout(function(){
        handleInput.call(element, e);
    }, 50);
}

something.bind("keyup", handleDelayedInput);

请注意,由于我们使用setTimout,我们需要找到一种方法将元素传递给超时处理函数。此外,在您的代码中,您使用handleInput(e)的返回值作为处理函数 - 而不是handleInput

我同意Mike的观点,如果您自己编写handleInput并且可以修改它,那么使用this而不是仅仅传递参数就没有意义了。如果您仍然希望将handleInput用作其他地方的直接处理程序,那么按照您拥有它的方式保留它是有意义的。

答案 3 :(得分:0)

你可以这样做:

handleInput = function(e) {
   var $this = $(this),
   id = $this.attr("id");
   setTimeout(function() {alert(id);}, 50);
}