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.