管理“;这个“;在事件/回调驱动的JavaScript应用程序中

Managing "this" in event/callback driven JavaScript applications

本文关键字:JavaScript 应用程序 这个 事件 管理 回调      更新时间:2023-09-26

我想知道在jQuery和Backbone.js 等框架中经常使用的回调中处理"this"引用的预期方法是什么

以下是我遇到问题的简化示例,使用Backbone.js和jQueryUI,但它并不是真正针对这些框架的。

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click(function() {
         // My code in here
      });
   },
   callMe: function() {
      alert('Rawr!');
   }
});

现在,我该如何从点击处理程序中引用MyView的实例呢?例如,如何从单击处理程序内部调用"callMe"?在处理程序之外,我只调用this。callMe();但是"this"被click处理程序中的DOM元素所取代。解决这一问题的最佳方法是什么?

最有效的方法是将this的结果存储在另一个变量中,然后在回调中使用;

var MyView = Backbone.View.extend({
   render: function() {
      var that = this;
      $('#mybutton').click(function() {
          // use that for MyView and this for the DOM element
      });
   },
   callMe: function() {
      alert('Rawr!');
   }
});

或者,您可以使用jQuery.proxy()或HTML5(注意向后兼容性)Function.prototype.bind()方法来定义this的值。显然,您将失去使用this引用DOM元素的能力,因此必须依赖Event对象的target属性;

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click((function(e) {
          // Use `this` for MyView and `e.target` for the DOM element
      }).bind(this));
   },
   callMe: function() {
      alert('Rawr!');
   }
});

或者:

var MyView = Backbone.View.extend({
   render: function() {
      $('#mybutton').click(jQuery.proxy(function(e) {
          // Use `this` for MyView and `e.target` for the DOM element
      }, this));
   },
   callMe: function() {
      alert('Rawr!');
   }
});

我就是这么做的。events属性是将大多数事件处理程序列在一个位置的简单方法。_.bindAll(this)将使this引用所有MyView函数内部的视图。

var MyView = Backbone.View.extend({
   events: {
     'click #mybutton': 'clickHandler'
   },
   initialize: function() {
     _.bindAll(this);
   }
   render: function() {
   },
   clickHandler: function() {
     this.callMe();
   },
   callMe: function() {
      alert('Rawr!');
   }
});