如何从事件处理程序引用对象实例

时间:2013-09-03 19:34:25

标签: javascript jquery

在下面的代码中,是否有更好的方法从handleClick()引用对象实例,而不是将其作为全局引用?

var Widget = function() {
  this.property = 'value';
  this.bindEvents();
}

Widget.prototype = {

  bindEvents: function() {
    $('button').on('click', this.handleClick);
  },

  handleClick: function() {
    var self = window.Widget;

    console.log(self.property);
  }
}

window.Widget = new Widget();

这个question问同样的事情,(未接受的)答案是将回调传递给$.on()并从那里调用处理程序,将实例作为参数传递给:

bindEvents: function() {
  var self = this;

  $('button').on('click', function() {
    self.handleClick.apply(self);
  });
}

这种传递实例的技术是否真正以正确的方式进行,或者除了我展示的两种方式之外还有其他方法吗?

5 个答案:

答案 0 :(得分:5)

该对象可以作为eventData传递给on(),如下所示:

var Widget = function () {
    this.property = 'value';
    this.bindEvents();
}

Widget.prototype = {

    bindEvents: function () {
        $('button').on('click', {o: this}, this.handleClick);
    },

    handleClick: function (e) {
        var widgt = e.data.o;
        console.log(widgt.property);
    }
}

window.Widget = new Widget();

FIDDLE

这样可以保持事件处理程序的范围。

答案 1 :(得分:1)

您可以使用bind()

bindEvents: function() {
  $('button').on('click', function() {
    this.handleClick();
  }.bind(this)); 
}

但是当谈到IE时,这只适用于IE> = 9。

在旧版IE中

编辑,你可以使用@Kevin B在评论中建议的jQuery的$.proxy()

bindEvents: function() {
  $('button').on('click', $.proxy(function() {
    this.handleClick();
  }, this)); 
}

答案 2 :(得分:0)

正如@kamituel所说,可以使用bind

Widget.prototype = {
  bindEvents: function() {
    $('button').on('click', this.handleClick.bind(this));
  },
  handleClick: function() {
    console.log(this.property);
  }
}

答案 3 :(得分:0)

指定的技术称为闭包,它是常用的。 但是,有时注意不要导致内存泄漏是很重要的。 你可以在这里阅读更多关于闭包的内容:

How do JavaScript closures work?

以及与闭包相关的内存泄漏,这里:

Memory leak risk in JavaScript closures

答案 4 :(得分:0)

保存this的最佳方法是 lambda函数

$('button').on('click', () => this.handleClick());

或者如果您想保留对事件的引用:

$('button').on('click', (event) => this.handleClick(event));

关于lambda函数的特别之处在于,您不必在(可能不同的)上下文中定义另一个函数。 lambda术语只是一条指令,因此是它在-中定义的对象的一部分-在您的情况下是window.Widget = new Widget()创建的实例。