在jQuery事件中控制'this'的值

Pat*_*bee 72 jquery scope this

我使用jQuery创建了一个'control',并使用jQuery.extend来帮助尽可能地将其作为OO.

在我的控件初始化期间,我连接各种点击事件,如此

jQuery('#available input', 
            this.controlDiv).bind('click', this, this.availableCategoryClick);
Run Code Online (Sandbox Code Playgroud)

请注意,我将'this'作为bind方法中的data参数.我这样做是为了让我可以获取附加到控件实例的数据而不是触发click事件的元素.

这很好用,但我怀疑有更好的方法

在过去使用过Prototype之后,我记得一个绑定语法,它允许你控制事件中'this'的值.

什么是jQuery方式?

Tor*_*ell 101

你可以使用jQuery.proxy()匿名函数,只是有点尴尬,'context'是第二个参数.

 $("#button").click($.proxy(function () {
     //use original 'this'
 },this));
Run Code Online (Sandbox Code Playgroud)


dav*_*ber 38

我喜欢你的方式,实际上使用类似的结构:

$('#available_input').bind('click', {self:this}, this.onClick);
Run Code Online (Sandbox Code Playgroud)

和第一行.onClick:

var self = event.data.self;
Run Code Online (Sandbox Code Playgroud)

我喜欢这种方式,因为这样你就可以点击元素(如此)和"this"对象作为self而不必使用闭包.


ben*_*les 32

jQuery有这个jQuery.proxy方法(自1.4以来可用).

例:

var Foo = {
  name: "foo",

  test: function() {
    alert(this.name)
  }
}

$("#test").click($.proxy(Foo.test, Foo))
// "foo" alerted
Run Code Online (Sandbox Code Playgroud)


Fer*_*yer 21

我认为jQuery没有内置功能.但您可以使用如下所示的辅助构造:

Function.prototype.createDelegate = function(scope) {
    var fn = this;
    return function() {
        // Forward to the original function using 'scope' as 'this'.
        return fn.apply(scope, arguments);
    }
}

// Then:
$(...).bind(..., obj.method.createDelegate(obj));
Run Code Online (Sandbox Code Playgroud)

这样,您可以使用createDelegate()创建动态"包装函数",该函数使用给定对象作为其"this"范围调用该方法.

例:

function foo() {
    alert(this);
}

var myfoo = foo.createDelegate("foobar");
myfoo(); // calls foo() with this = "foobar"
Run Code Online (Sandbox Code Playgroud)

  • 伙计们,这篇文章写于2009年2月,此时还没有`jQuery.proxy()`(出现在2010年1月第1版).不需要downvote. (40认同)
  • 是不是给出了最多票数的最佳答案?如果过时的答案得到落实或删除,我会感激不尽.它有助于避免误导恕我直言. (5认同)
  • @ben:答案可能已经过时,但是当答案相关时,没有理由剥夺作者所获得的学分.我认为为过时的答案建议一个标志功能比向下投票一次正确的答案要好. (2认同)

JLR*_*she 5

符合HTML 5的浏览器提供了一种绑定方法,Function.prototype它可能是最干净的语法,并且不依赖于框架,但是在IE 9之前它没有内置到IE中.(但是没有它的浏览器有一个polyfill.)

根据您的示例,您可以像这样使用它:

jQuery('#available input', 
        this.controlDiv).bind('click', this.availableCategoryClick.bind(this));
Run Code Online (Sandbox Code Playgroud)

(旁注:bind本声明中的第一部分是jQuery的一部分,与之无关Function.prototype.bind)

或者使用稍微简洁和最新的jQuery(并消除两种不同类型的混淆bind):

$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));
Run Code Online (Sandbox Code Playgroud)