JavaScript partially applied function - How to bind only the 2nd parameter?

后端 未结 4 1248
忘掉有多难
忘掉有多难 2020-12-23 19:59

Sorry if I\'m missing something obvious, but I can\'t figure out how to bind a specific (nth) argument of a function in javascript. Most of my functional programming I\'ve

相关标签:
4条回答
  • 2020-12-23 20:29

    Of course you can do it. Here's an ES6 solution using the spread operator (...), since it's a bit more compact.

    // Bind arguments starting after however many are passed in.
    function bind_trailing_args(fn, ...bound_args) {
        return function(...args) {
            return fn(...args, ...bound_args);
        };
    }
    

    If you'd prefer to specify the position at which binding starts:

    // Bind arguments starting with argument number "n".
    function bind_args_from_n(fn, n, ...bound_args) {
        return function(...args) {
            return fn(...args.slice(0, n-1), ...bound_args);
        };
    }
    

    IN ES5, you have to muck around with constructing argument lists.

    // ES5 version: construct arguments lists yourself
    function bind_trailing_args(fn) {
        var bound_args = [].slice.call(arguments, 1);
        return function() {
            var args = [].concat.call(arguments, bound_args);
            return fn.apply(this, args);
        };
    }
    

    Unlike the first two examples, this one handles this properly.

    In the context of your example:

    var addThree = bind_trailing_args(add, 3);
    addThree(1) // calls add(1, 3)
    

    You could also consider using one of the functional programming libraries available for JS, such as http://osteele.com/sources/javascript/functional/. The thing you want is called rcurry there.

    0 讨论(0)
  • 2020-12-23 20:37

    Well. I'll just throw this out there.

    var add = function(a,b) {
      return a + b;
    };
    
    var addThree = function(a) {
      return add(a,3);
    };
    
    add(1,2);
    addThree(4);
    

    Maybe it will be ok for some.

    0 讨论(0)
  • 2020-12-23 20:38

    You can use lodash's _.bind to achieve this:

    var add = function(a, b) {
      document.write(a + b);
    };
    
    // Bind to first parameter (Nothing special here)
    var bound = _.bind(add, null, 3);
    bound(4);
    // → 7
    
    // Bind to second parameter by skipping the first one with "_"
    var bound = _.bind(add, null, _, 4);
    bound(3);
    // → 7
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script>

    I am usually against libraries and prefer coding my own utility functions, but an exception can easily be made for lodash. I would highly suggest you check its documentation whenever you have a "This must be in the language somewhere!" moment. It fills in a lot of blanks in JavaScript.

    0 讨论(0)
  • 2020-12-23 20:40

    you can try this:

    Function.prototype.bindThemAll = function bindThemAll(thisArg, ...boundArgs) 
      (boundArgs.fn = this, function(...args) boundArgs.fn.call(thisArg || this, ...boundArgs.map((el) => el || args.shift()), ...args));
    
    function fn() console.log("fn:", arguments.callee, "this:", this, "args:", arguments)
    
    var x = {a: 5};
    
    var bfn = fn.bindThemAll(x, null, 2)
    bfn(1,3)
    x.bfn = fn.bindThemAll(null, null, 2)
    x.bfn(1,3)

    bound arguments with null or undefined will be replaced with the function arguments in order, the remaining arguments will be appended to the end. an object will be used if it is bound otherwise the current this will be used...

    see console for results!

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