Javascript lodash.js在function.apply上的部分应用程序
给定以下函数时,使用Javascript lodash.js在function.apply上的部分应用程序,javascript,functional-programming,underscore.js,lodash,Javascript,Functional Programming,Underscore.js,Lodash,给定以下函数时,使用\uu.partial函数会引发错误: function foo(x, y) { return 1 + 2; } p = _.partial(foo.apply, null); p([1,2]); 我得到: TypeError:Function.prototype.apply在[object Window]上被调用,它是一个对象而不是函数 我在这里做错了什么?还有其他方法可以实现我的目标吗?我相信你的目标是: function foo(x, y) { return x +
\uu.partial
函数会引发错误:
function foo(x, y) { return 1 + 2; }
p = _.partial(foo.apply, null);
p([1,2]);
我得到:
TypeError:Function.prototype.apply在[object Window]上被调用,它是一个对象而不是函数
我在这里做错了什么?还有其他方法可以实现我的目标吗?我相信你的目标是:
function foo(x, y) { return x + y; }
p = Function.apply.bind(foo, null);
p([1,2]); // ===3
我能做的最接近下划线的事情是通过uz.bind:
function foo(x, y) { return x + y; }
p = _.bind(foo.apply, foo, 0);
p([1,2]); // ===3
您可能还想考虑对该函数的另一种灵活使用,以对2个以上元素的整个数组求和:
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
冒着误解问题的风险,我想与大家分享一个我在类似情况下偶然发现的策略 问题: 在我的例子中,问题是有时我需要调用一个带有一些参数的函数(
foo
),而不改变this
上下文。不幸的是,参数列表是不确定的——有时可能有2个,有时可能有3个,等等。由于\uu.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));
}
从lodash 3.2开始,您将使用以下功能:
function foo(x, y) { return x + y; }
var p = _.spread(foo);
p([ 1, 2 ]); // → 3
您不使用任何参数,因此通常使用apply或currying没有任何意义。这是有效的:u.partial(foo)(1,2),foo和foo.apply是两个不同的函数。@erdeszt关键是将参数(除了第一个)作为数组传递,这就是我必须使用foo.apply的原因。谢谢,这很有效,但是你知道为什么x.partial会产生错误吗?关于你的编辑,我实际上是这样做的:x(xs).zip(ys).zip(zs).map(Function.apply.bind(foo,null));