我正在尝试将值映射到一个函数,该函数将接受两个数字相乘但却无法这样做(如果这没有意义,请查看下面的示例)。
我有一个数组,我想加倍/三倍/四倍......这个数组的值。我创建了可以执行此操作的函数,并将这些double()
和triple()
投放到map()
。
var arr = [1, 2, 3, 4, 5];
function double(num) {
return num * 2;
}
function triple(num) {
return num * 3;
}
console.log( arr.map(double) );
console.log( arr.map(triple) );
如果我想将这些值乘以5或10,该解决方案是不可扩展的?我需要一个更抽象的函数来获取乘法的参数。我很困惑如何做到这一点。到目前为止我的尝试是:
var arr = [1, 2, 3, 4, 5];
function multiply(num, multiplyBy) {
return num * multiplyBy;
}
console.log( arr.map(multiplyBy(4) ); // Uncaught TypeError: NaN is not a function
我如何传递multiply()
multiplyBy
参数?
答案 0 :(得分:18)
您正在寻找partial application。例如,可以使用bind
(或许多功能库附带的辅助函数,如in Underscore)来完成:
arr.map(multiplyBy.bind(null, 4))
然而简单的箭头功能会更容易:
arr.map(x => multiplyBy(4, x))
但是如果curry multiplyBy
function multiplyBy(multiplier) {
return function(num) {
return num * multiplier;
};
}
// ES6 arrow functions:
const multiplyBy = multiplier => num => num * multiplier;
arr.map(multiplyBy(4));
函数,你也可以免费获得部分申请,获取乘数并返回一个新函数:
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax
to use near 'unsigned not null, `address_1` varchar(191) unsigned not null, `address_2` varch' at line 1
答案 1 :(得分:17)
你可以做一个叫做工厂的事情。实际上,您可以创建一个功能,返回另一个根据您的需求量身定制的功能。在这种情况下,一个匿名的。
var arr = [1, 2, 3, 4, 5];
function multiplyBy(scale) {
return function(num){
return num * scale;
}
}
console.log( arr.map( multiplyBy(4) ));
这是有效的,因为返回的匿名函数的范围在工厂的范围内。因此,每当我们生成一个新函数时,它将保留为其生成而给出的scale
值。
编辑:@Bergi答案的最后一部分和我的一样。这个概念显然被称为currying。谢谢@Bergi!正如Bergi所说,工厂模式更经常应用于对象的生成,但这是我当时唯一能想到的东西,javascript有点像对象这样的函数。在这种特定情况下,它们实际上是相似的。
答案 2 :(得分:10)
您可以使用Function.prototype.bind
创建带有绑定参数的新函数。例如
var arr = [1, 2, 3, 4, 5];
function multiplyBy(multiplyBy, num) {
// note the "num" argument must come last if it is to represent the argument from "map"
return num * multiplyBy;
}
console.log( arr.map(multiplyBy.bind(null, 4)) ); // null is for the "this" argument