鉴于以下函数,_.partial
函数的使用会引发错误:
function foo(x, y) { return 1 + 2; }
p = _.partial(foo.apply, null);
p([1,2]);
我明白了:
TypeError:在[object Window]上调用了Function.prototype.apply,它是一个对象而不是一个函数
我在这里做错了什么?还有另一种方法来实现我正在做的事情吗?
答案 0 :(得分:3)
我相信你的目标:
function foo(x, y) { return x + y; }
p = Function.apply.bind(foo, null);
p([1,2]); // ===3
最接近我可以通过_.bind得到下划线:
function foo(x, y) { return x + y; }
p = _.bind(foo.apply, foo, 0);
p([1,2]); // ===3
您可能还想考虑另一个灵活使用该函数,对两个以上元素的整数数组求和:
function foo(x, y) { return x + y; }
_.reduce([1,2,3,4,5], foo); // == 15
或使用vanillaJS:
function foo(x, y) { return x + y; }
[1,2,3,4,5].reduce(foo); // == 15
答案 1 :(得分:2)
冒着误解这个问题的风险,我想分享一个我偶然发现类似情况的策略。
在我的例子中,问题是有时我需要使用一些参数调用函数(foo
)而不更改this
上下文。不幸的是,参数列表不是确定性的 - 有时候可能有2个,有时可能有3个等等。而且由于_.partial
期望每个参数作为一个单独的参数传递,我最初被难倒了。例如:
// 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])
当您想要使用apply
而不是call
来正常调用函数时,这是一个相同的用例。所以经过一段时间的闲逛之后,我意识到我可以做到:
var argsToLodashPartialFn = [foo].concat(args);
var newFn = _.partial.apply(null, argsToLodashPartialFn);
或者,更简洁:
var newFn = partialApply(foo, args);
// === newFn(args[0], args[1], ...., args[n])
newFn();
这是作为可重用函数的实现:
/**
* 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));
}
答案 2 :(得分:1)
从lodash 3.2开始,您将使用spread()函数:
function foo(x, y) { return x + y; }
var p = _.spread(foo);
p([ 1, 2 ]); // → 3