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

后端 未结 2 1314
再見小時候
再見小時候 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 04:55

    when this in your callback belongs to the scope of callback bind not the scope of the event.

    this might work but I am not sure i understand what you are trying to do

    $(".selector").on("click", function(event){
        callback.bind(event.type, param1, param2)
    });
    

    this points to the dom element your event occured while the event already has the type which you want to pass to the 2nd bind (2nd because in theory your .on() is a bind as well)

    0 讨论(0)
  • 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);
    }
    <div class="selector">Click me</div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


    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).

    0 讨论(0)
提交回复
热议问题