最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What's the difference between $.proxy and the native js 'call''apply'? - St

programmeradmin1浏览0评论

I believe they both allow you to control the value of 'this', but beyond that, I'm a little unclear and Google/SO isn't helping much so far. Any clarification appreciated. I did find this, but I'm skeptical that it tells the whole story:

"When I first learned about jQuery's proxy() method, I thought it was a little silly; after all, Javascript already has call() and apply() methods for changing execution context. But, once you realize that jQuery's proxy() method allows you to easily bind() and unbind() event handlers regardless of context, it becomes obvious just how powerful this method is.

I believe they both allow you to control the value of 'this', but beyond that, I'm a little unclear and Google/SO isn't helping much so far. Any clarification appreciated. I did find this, but I'm skeptical that it tells the whole story:

"When I first learned about jQuery's proxy() method, I thought it was a little silly; after all, Javascript already has call() and apply() methods for changing execution context. But, once you realize that jQuery's proxy() method allows you to easily bind() and unbind() event handlers regardless of context, it becomes obvious just how powerful this method is.

Share Improve this question edited Feb 20, 2013 at 23:23 GregT asked Feb 20, 2013 at 23:11 GregTGregT 1,3203 gold badges16 silver badges25 bronze badges 5
  • Helpful search terms for Google-fu: JavaScript execution context. – cmbuckley Commented Feb 20, 2013 at 23:13
  • 2 A lot of jQuery stuff is completely pointless. The fact that many people think it's good to use $(this).attr('id') instead of this.id, for instant. I haven't looked at $.proxy, but it's entirely possible that it's just the same: redundant and pointless. – Niet the Dark Absol Commented Feb 20, 2013 at 23:14
  • @Kolink it is the thing as you writing a function that returns a function that returns apply. Almost every library out there has this method. – epascarello Commented Feb 20, 2013 at 23:23
  • .proxy is actually a polyfill for bind (as in "creating a new function bound to a given context"). apply is just the means to accomplish this. So comparing .proxy to apply/call does not make sense. – Yoshi Commented Feb 20, 2013 at 23:23
  • A better comparison is between $.proxy() and the .bind() API in newer browsers. (Not to be confused with jQuery's .bind(), which is now deprecated in favor of .on() anyway.) – Pointy Commented Feb 20, 2013 at 23:26
Add a comment  | 

3 Answers 3

Reset to default 12

call/apply are a single-shot invocation. $.proxy creates a new function permanently bound to something:

fn.call(foo);  //call once

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

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

As a simplification (very simplified), $.proxy is creating a new function that calls call:

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

It is analogous to ES5's Function.prototype.bind

Take a look at the jQuery source:

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;
},

If you remove the caching code and make it a little shorter, you essentially get .apply() (I think I translated the slicing code correctly):

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

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

$.proxy you can call on a function and the function it returns will ALWAYS have a particular context. That means that if you ran

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

It would log 1 because the function is always bound to the object that was initially passed to proxy

发布评论

评论列表(0)

  1. 暂无评论