$ .proxy和原生js'call'/'apply'之间有什么区别?

时间:2013-02-20 23:11:29

标签: javascript jquery

我相信他们都允许你控制'this'的价值,但除此之外,我有点不清楚,谷歌/ SO到目前为止没有多少帮助。任何澄清都表示赞赏。我确实找到了这个,但我怀疑它是否讲述了整个故事:

  

“当我第一次学习jQuery的proxy()方法时,我认为是   有点傻毕竟,Javascript已经有call()和apply()   更改执行上下文的方法。但是,一旦你意识到这一点   jQuery的proxy()方法允许您轻松地绑定()和取消绑定()事件   处理程序无论上下文如何,它变得明显有多强大   这个方法是。

3 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:5)

看一下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)));
    };
}

答案 2 :(得分:1)

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

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

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