【问题标题】:Setting anonymous function scope of 'this' in jQuery utility / ajax methods在 jQuery 实用程序/ajax 方法中设置“this”的匿名函数范围
【发布时间】:2011-01-08 20:28:08
【问题描述】:

this blog post 中所述,您可以在Javascript 的匿名函数中设置this 的范围。

在对 AJAX 请求的 success 的匿名函数调用中,是否有更优雅的方法来确定 this 的范围(即不使用 that)?

例如:

var Foo = {

  bar: function(id) {

    var that = this;

    $.ajax({
      url: "www.somedomain.com/ajax_handler",
      success: function(data) {
        that._updateDiv(id, data);
      }
    });

  },

  _updateDiv: function(id, data) {

    $(id).innerHTML = data;

  }

};

var foo = new Foo;
foo.bar('mydiv');

使用调用但仍需将父对象作用域命名为that

success: function(data) {
    (function() {
      this._updateDiv(id, data);
    }).call(that);
}

【问题讨论】:

  • that=this 模式很优雅,也很简单,并且(作为一种常见的模式)可识别。不要与之抗争。

标签: javascript jquery scope anonymous-function


【解决方案1】:

在 jQuery 1.4 中你有 $.proxy 方法,你可以简单地写:

 //...
 bar: function(id) {
    $.ajax({
      url: "someurl",
      success: $.proxy(this, '_updateDiv')
    });
  },
  //...

$.proxy 接受一个对象,该对象将用作this 值,它可以接受一个字符串(该对象的成员)或一个函数,它将返回一个新函数,该函数将始终具有特定范围。

另一个替代方法是 bind 函数,现在 ECMAScript 第五版标准的一部分是最好的:

//...
  bar: function(id) {
    $.ajax({
      url: "someurl",
      success: function(data) {
        this._updateDiv(id, data);
      }.bind(this)
    });
  },
//...

这个功能很快就会原生提供,当 JavaScript 引擎完全实现 ES5 标准时,目前你可以使用以下 8 行长的实现:

// The .bind method from Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

【讨论】:

  • 谢谢,我想这个问题更多的是关于个人品味。我喜欢绑定方法。我开悟了。
【解决方案2】:

$.ajax() 函数已经以 context 参数的形式提供了一种简洁的方法:

$.ajax({
  url: "www.somedomain.com/ajax_handler",
  context: this,
  success: function(data) {
    this._updateDiv(id, data);
  }
});

虽然CMS outlines 的技术更适合一般用途。

【讨论】:

  • 这是最好的方法。它不仅更加清晰,而且对于 GC 来说更健康,因为它不会创建像 $.proxy 这样的闭包,所以如果您发出大量请求,那就是额外的责任了..
猜你喜欢
  • 2011-10-27
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 2010-10-22
  • 2012-05-10
  • 1970-01-01
相关资源
最近更新 更多