Use bound this and this of function scope in a function bound with bind()

后端 未结 2 1316
再見小時候
再見小時候 2021-01-26 04:50

I have the following function call:

$(\".selector\").on(\"click\", callback.bind(this, param1, param2));

Inside my callback function I would li

2条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-26 05:03

    Inside my callback function I would like to use the bound this as well as the this from the function scope.

    In that specific example, you can use the currentTarget property of the event:

    function callback(p1, p2, e) {
        // Use e.currentTarget
    }
    

    Note that there we have p1 and p2, which are the arguments you bound to the callback, followed by e which is the event argument passed when the click occurs.


    In the general case, though, you wouldn't want Function#bind, because it prevents your accessing the this that the function was called with.

    You can provide yourself a Function#curry (see below for why that name) that leaves this alone, and then curry the current this, e.g.:

    $(".selector").on("click", callback.curry(this, param1, param2));
    

    Where an unoptimized version of curry looks like this:

    Function.prototype.curry = function() {
        var f = this;
        var boundArgs = Array.prototype.slice.call(arguments);
        return function() {
            return f.apply(this, boundArgs.concat(Array.prototype.slice.call(arguments)));
        };
    };
    

    Live Example:

    Function.prototype.curry = function() {
      var f = this;
      var boundArgs = Array.prototype.slice.call(arguments);
      return function() {
        return f.apply(this, boundArgs.concat(Array.prototype.slice.call(arguments)));
      };
    };
    
    var obj = {
      foo: 42,
      method: function() {
        $(".selector").on("click", callback.curry(this, "param1", "param2"));
      }
    };
    obj.method();
    
    function callback(t, p1, p2, e) {
      snippet.log("t.foo = " + t.foo);
      snippet.log("this.tagName = " + this.tagName);
      snippet.log("e.currentTarget.tagName = " + e.currentTarget.tagName);
      snippet.log("p1 = " + p1);
      snippet.log("p2 = " + p2);
    }
    Click me


    Why curry?

    Creating a function from another function with (some of) that function's arguments pre-supplied is frquently called "currying," after the mathmatician Haskell Curry. It's also called "partial application" although I think (this is not my area of expertise) that term has a slightly more specific meaning, at least in functional programming (such as the kind you do in the language Haskell—  also named after Haskell Curry).

提交回复
热议问题