Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript lodash.js在function.apply上的部分应用程序_Javascript_Functional Programming_Underscore.js_Lodash - Fatal编程技术网

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));