从另一个函数获得$this值

Reaching $this value from another function

本文关键字:this 另一个 函数      更新时间:2023-09-26

我的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);说未定义,因为我认为我无法将 this 传递给该函数。

我说的对吗?我该如何解决?有没有更好的方法可以做到这一点?

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

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

请注意,使用 on() 而不是现在首选用法的bind()

当 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

不过,我同意迈克的观点,如果您自己编写了handleInput并且可以对其进行修改,那么使用this而不仅仅是传递参数是没有意义的。如果您仍然想在其他地方使用 handleInput 作为直接处理程序,那么保持它的方式是有意义的。

使用 apply 函数:

var handleDelayedInput = function(e) {
    var that = this;
    setTimeout(function() {
        handleInput.apply(that, [e]);
    }, 50);
}
something.bind("keyup", handleDelayedInput); // Assuming something is a 
                                             // jQuery object

这是一个工作 jsFiddle。

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

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

你可以

这样做:

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