jQuery.proxy()的使用方法

70

我正在阅读关于jQuery.proxy()的API文档。它看起来很有前途,但我想知道在什么情况下最好使用它。有人可以启发一下我吗?


请参阅https://dev59.com/o2445IYBdhLWcg3wM3fx#4986562,了解一个很好的解释。 - Paul
3个回答

142
当您需要一个将this值绑定到特定对象的函数时,比如回调函数,如事件处理程序、AJAX回调、超时、间隔、自定义对象等。
这只是一个制造出来的例子,说明在某些情况下可能会有用。假设有一个名为Person的对象,它有一个属性名字。它还链接到一个文本输入元素,每当输入值改变时,此人物对象中的名称也会更新。
function Person(el) {
    this.name = '';

    $(el).change(function(event) {
        // Want to update this.name of the Person object,
        // but can't because this here refers to the element
        // that triggered the change event.
    });
}

我们经常使用的一种解决方案是将this上下文存储在变量中,并在回调函数中使用该变量,例如:

function Person(el) {
    this.name = '';

    var self = this; // store reference to this

    $(el).change(function(event) {
        self.name = this.value; // captures self in a closure
    });
}

另外,我们也可以在这里使用 jQuery.proxy,这样对 this 的引用将指向 Person 对象,而不是触发事件的元素。

function Person(el) {
    this.name = '';

    $(el).change(jQuery.proxy(function(event) {
        this.name = event.target.value;
    }, this));
}

请注意,此功能已标准化为ECMAScript 5,现在包括从借用的bind方法,并已在一些浏览器上提供。
function Person(el) {
    this.name = '';

    $(el).change(function(event) {
        this.name = event.target.value;
    }.bind(this)); // we're binding the function to the object of person
}

34
谢谢您提到这个已经被引入 ECMAscript 的事实。 - Mike Sherov
1
使用常规闭包还是使用$.proxy更好(更快,更高效)? - Anson MacKeracher
4
@AnsonMacKeracher,最好且更快的方法是不使用closure,而是使用代理静态函数。这些答案没有展示代理可以与静态函数一起使用,而self = this的方法只能在内联创建函数时使用。 - Esailija
3
进一步说,在ECMAScript 6(ES6)中,箭头函数是最好的选择(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)function Person(el) { this.name = ''; $(el).change((event) => { this.name = event.target.value; }); } - TypingTurtle

17

这只是一种为闭包设置上下文的速记方法,例如:

$(".myClass").click(function() {
  setTimeout(function() {
    alert(this); //window
  }, 1000);
});

然而,我们经常希望this与我们所在的方法保持不变,这正是$.proxy()要用的地方,像这样:

$("button").click(function() {
  setTimeout($.proxy(function() {
    alert(this); //button
  }, this), 1000);
});​

它通常用于延迟调用,或者在您不想使用冗长的闭包声明方法的任何地方。将上下文指向对象的字符串方法...嗯,我还没有在日常代码中发现实际用途,但我相信有应用场景,只取决于您的对象/事件结构。


14

例如,如果您想创建回调函数。而不是:

var that = this;

$('button').click(function() {
    that.someMethod();
});

你可以这样做:

$('button').click($.proxy(this.someMethod, this));

或者,如果您创建了一个接受回调函数的插件,并且必须为回调函数设置特定上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接