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

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.


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.


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.