在jQuery事件中控制“ this”的值


74

我使用jQuery创建了一个“控件”,并使用jQuery.extend来帮助使其尽可能地面向对象。

在控件初始化期间,我连接了各种单击事件,如下所示

jQuery('#available input', 
            this.controlDiv).bind('click', this, this.availableCategoryClick);

注意,我正在将“ this”作为bind方法中的数据参数。我这样做是为了获得附加到控件实例的数据,而不是从激发click事件的元素中获取数据。

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

过去曾经使用过Prototype,但我记得绑定语法使您可以控制事件中'this'的值。

jQuery的方式是什么?


Dunno,为什么您要制作jQuery OO是因为jQuery比OO更具有功能。
cletus

Answers:


104

您可以将其jQuery.proxy()与匿名函数一起使用,只是有点尴尬地认为“上下文”是第二个参数。

 $("#button").click($.proxy(function () {
     //use original 'this'
 },this));

39

我喜欢您的方式,实际上使用了类似的构造:

$('#available_input').bind('click', {self:this}, this.onClick);

以及this.onClick的第一行:

var self = event.data.self;

我喜欢这种方式,因为这样您既可以单击元素(这样)又可以将“ this”对象作为自身,而不必使用闭包。


这实际上是非常有用的,是迄今为止我所见过的最好的方法..谢谢花花公子!
尤金·库兹曼科

干净的解决方案。我喜欢它。
Gad D Lord

你像我一样聪明:-D
peterchaula

这是最好的。没有其他复杂的关闭代码。谢谢
Kannan J

33

jQuery具有 jQuery.proxy方法(从1.4开始可用)。

例:

var Foo = {
  name: "foo",

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

$("#test").click($.proxy(Foo.test, Foo))
// "foo" alerted

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));

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

例:

function foo() {
    alert(this);
}

var myfoo = foo.createDelegate("foobar");
myfoo(); // calls foo() with this = "foobar"

40
伙计们,这篇文章写于2009年2月,目前还没有jQuery.proxy()(出现在2010年1月的v.1.4中)。无需投票。
Ferdinand Beyer

5
给出最好的答案,投票最多不是吗?如果过时的答案被拒绝或删除,我将不胜感激。它有助于避免误导恕我直言。
2014年

1
当然,最好的答案应该会得到最多的选票,就像这里的情况一样。但这并不意味着次优的答案应该被否决。那会降低声誉,而且根本不公平。您希望我做什么?定期检查并修改我的古老答案?
费迪南德·拜尔

1
不,我绝不声称您做错了什么。恕我直言,这种情况只是SO机制(至少AFAIK)没有很好地涵盖。某个时候非常合适的答案会被投票并留在那儿,即使它们随着时间的推移而变得不合适,因为出现了其他方法,它们的性能优于旧机制。恕我直言,最好的办法是标记这些答案,以使作者得到通知并可以做出反应,或者给出某种指示,表明答案可能已过时。
2014年

4
@ben:答案可能已经过时,但这没有理由剥夺作者在相关答案时所获得的功劳。我认为建议为过时的答案提供标记功能比对曾经是正确答案的内容进行否决投票更好。
Mike Purcell,2015年

5

HTML 5兼容的浏览器提供一个绑定方法Function.prototype,其是,可能是最清洁的语法,而不是框架依赖性的,虽然它不内置IE IE为止9.(有一个填充工具为没有它的浏览器,虽然。)

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

jQuery('#available input', 
        this.controlDiv).bind('click', this.availableCategoryClick.bind(this));

(旁注:bind此语句的第一部分是jQuery的一部分,与无关Function.prototype.bind

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

$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));

4

您可以使用如下所示的javascript bind方法:

var coolFunction = function(){
  // here whatever involving this
     alert(this.coolValue);
}

var object = {coolValue: "bla"};


$("#bla").bind('click', coolFunction.bind(object));

las,这似乎仅在JS 1.8.5中有效,这使诸如IE8之类的浏览器无法使用。
路加H

1
@LukeH绑定方法只是一些js代码.. developer.mozilla.org/en-US/docs/JavaScript/Reference/...
奥兰多

1
@JLRishe您可以使用此填充工具为IE8
奥兰多

@奥兰多你的确是正确的。我现在要删除我之前的评论。
JLRishe 2014年

2

jQuery不支持绑定,首选方式是使用函数。

因为在Javascript中,this.availableCategoryClick并不意味着对该对象调用availableCategoryClick函数,所以jQuery建议使用以下首选语法:

var self = this;
jQuery('#available input', self.controlDiv).bind('click', function(event)
{
   self.availableCategoryClick(event);
});

Java语言中的OO概念很难理解,函数式编程通常更容易理解。


1

看到函数会改变范围,最常见的方法是使用手动操作var self = this

var self = this

$('.some_selector').each(function(){
  // refer to 'self' here
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.