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

Gre*_*egT 9 javascript jquery

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

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

Den*_*nis 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
Run Code Online (Sandbox Code Playgroud)

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

$.proxy = function(fn, newThis) {
    return function() {
        fn.call(newThis);
    }
}
Run Code Online (Sandbox Code Playgroud)

它类似于ES5 Function.prototype.bind


Ble*_*der 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;
},
Run Code Online (Sandbox Code Playgroud)

如果你删除缓存代码并使其缩短,你基本上得到.apply()(我认为我正确地翻译了切片代码):

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

    return function() {
        return fn.apply(context || this, args.concat([].slice.call(arguments)));
    };
}
Run Code Online (Sandbox Code Playgroud)