Given the following function, the usage of _.partial
function throws an error:
function foo(x, y) { return 1 + 2; }
p = _.partial(foo.apply, null);
p([1,2]);
I get:
TypeError: Function.prototype.apply was called on [object Window], which is a object and not a function
What am I doing incorrectly here? Is there another way to achieve what I'm doing?
i belive this what you're going for:
function foo(x, y) { return x + y; }
p = Function.apply.bind(foo, null);
p([1,2]); // ===3
the closest i can get underscore to do is via _.bind:
function foo(x, y) { return x + y; }
p = _.bind(foo.apply, foo, 0);
p([1,2]); // ===3
you may also want to consider another flexible use of that function, to sum a whole array of more than 2 elements:
function foo(x, y) { return x + y; }
_.reduce([1,2,3,4,5], foo); // == 15
or using vanillaJS:
function foo(x, y) { return x + y; }
[1,2,3,4,5].reduce(foo); // == 15
At the risk of misunderstanding the issue here, I wanted to share a tactic I just stumbled upon for a similar situation.
The problem, in my case, is that sometimes I need to call a function (foo
) with some arguments without changing the this
context. Unfortunately, the list of arguments is not deterministic-- sometimes there might be 2, sometimes there might be 3, etc. And since _.partial
expects each argument to be passed in as a separate argument, I was initially stumped. For example:
// some dynamic array of args
var args = [new Error(), [{id: 3}, {id: 7}], function cb() {}];
// the function we want the partially applied to
var fn = function foo ( /* ...want `args` in here... */ ) {
// ..implementation...
}
// can't do it with normal _.partial() usage...
// var newFn = _.partial(fn, args[0], args[1], ... args[args.length])
This is much the same use case when you'd want to use apply
instead of call
to invoke a function normally. So after putzing around w/ it for a while, I realized I could just do:
var argsToLodashPartialFn = [foo].concat(args);
var newFn = _.partial.apply(null, argsToLodashPartialFn);
Or, more concisely:
var newFn = partialApply(foo, args);
// === newFn(args[0], args[1], ...., args[n])
newFn();
And here's the implementation as a reusable function:
/**
* partialApply()
*
* Like `_.partial(fn, arg0, arg1, ..., argN)`,
* but for a dynamic array of arguments:
*
* @param {Function} fn
* @param {Array} args
* @return {Function}
*/
function partialApply (fn, args) {
return _.partial.apply(null, [fn].concat(args));
}
As of lodash 3.2, you would use the spread() function for this:
function foo(x, y) { return x + y; }
var p = _.spread(foo);
p([ 1, 2 ]); // → 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With