9

我相信它们都允许您控制“this”的值,但除此之外,我有点不清楚,到目前为止,Google/SO 并没有多大帮助。任何澄清表示赞赏。我确实找到了这个,但我怀疑它是否能说明整个故事:

“当我第一次了解 jQuery 的 proxy() 方法时,我觉得有点傻;毕竟 Javascript 已经有了 call() 和 apply() 方法来改变执行上下文。但是,一旦你意识到 jQuery 的 proxy() 方法无论上下文如何,您都可以轻松地 bind() 和 unbind() 事件处理程序,很明显这个方法有多强大。

4

3 回答 3

12

call/apply 是单次调用。$.proxy 创建了一个永久绑定到某物的新函数:

fn.call(foo);  //call once

var otherFn = $.proxy(fn, foo);  // you can call it again later

var otherOtherFn = fn.bind(foo);  // ES5 standard way

作为简化(非常简化),$.proxy正在创建一个新函数,该函数调用call

$.proxy = function(fn, newThis) {
    return function() {
        fn.call(newThis);
    }
}

它类似于 ES5 的Function.prototype.bind

于 2013-02-20T23:24:57.170 回答
6

看一下 jQuery 源码:

proxy: function( fn, context ) {
    var tmp, args, proxy;

    if ( typeof context === "string" ) {
        tmp = fn[ context ];
        context = fn;
        fn = tmp;
    }

    // Quick check to determine if target is callable, in the spec
    // this throws a TypeError, but we will just return undefined.
    if ( !jQuery.isFunction( fn ) ) {
        return undefined;
    }

    // Simulated bind
    args = core_slice.call( arguments, 2 );
    proxy = function() {
        return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
    };

    // Set the guid of unique handler to the same of original handler, so it can be removed
    proxy.guid = fn.guid = fn.guid || jQuery.guid++;

    return proxy;
},

如果你删除缓存代码并让它更短一点,你基本上得到.apply()(我想我正确地翻译了切片代码):

proxy: function(fn, context) {
    var args = [].slice.call(arguments, 2);

    return function() {
        return fn.apply(context || this, args.concat([].slice.call(arguments)));
    };
}
于 2013-02-20T23:20:30.090 回答
1

$.proxy你可以调用一个函数,它返回的函数总是有一个特定的上下文。这意味着如果你跑

$.proxy(function() {console.log(this.val)}, {val: 1}).call({val: 2});

它会记录1,因为该函数始终绑定到最初传递给的对象proxy

于 2013-02-20T23:24:23.160 回答