在事件/回调驱动的JavaScript应用程序中管理"this"

Tom*_*ess 1 javascript jquery jquery-ui backbone.js

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

这是我遇到问题的简化示例,使用Backbone.js和jQuery UI,但它并不是特定于这些框架.

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

   callMe: function() {
      alert('Rawr!');
   }
});
Run Code Online (Sandbox Code Playgroud)

现在,我如何从点击处理程序中引用MyView实例?例如,我如何从点击处理程序中调用"callMe"?在处理程序之外我只是调用this.callMe(); 但是"this"会被click处理程序中的DOM元素替换.解决这个问题的最佳方法是什么?

Mat*_*att 8

最有效的方法是将结果存储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!');
   }
});
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用jQuery.proxy()HTML 5(谨防向后兼容性)Function.prototype.bind()方法来定义其值this.显然,你已经失去了this用于引用DOM元素的能力,因此必须依赖于对象的target属性Event;

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!');
   }
});
Run Code Online (Sandbox Code Playgroud)

要么:

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!');
   }
});
Run Code Online (Sandbox Code Playgroud)