如何将参数传递给array.map()?

Jon*_*Jon 20 javascript

我正在尝试将值映射到一个函数,该函数将接受两个数字来乘以但是这样做有困难(如果这没有意义,请看下面的示例).

我有一个数组,我想加倍/三倍/四倍......这个数组的值.我创建功能,将做到这一点,我喂这些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) );
Run Code Online (Sandbox Code Playgroud)

这个解决方案是不可扩展的,如果我想将值乘以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
Run Code Online (Sandbox Code Playgroud)

我将如何传递multiply()multiplyBy参数?

The*_*Man 21

你可以做一个叫工厂的事情.实际上,您可以创建一个功能,返回另一个根据您的需求量身定制的功能.在这种情况下,一个匿名的.

var arr = [1, 2, 3, 4, 5];

function multiplyBy(scale) {
    return function(num){
        return num * scale;
    }
}

console.log( arr.map( multiplyBy(4) ));
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为返回的匿名函数的范围在工厂的范围内.因此,每当我们生成一个新函数时,它将保留scale为其生成所给出的值.

编辑:@Bergi答案的最后一部分和我的一样.这个概念显然被称为currying.谢谢@Bergi!正如Bergi所说,工厂模式更经常应用于对象的生成,但这是我当时唯一能想到的东西,javascript有点像对象这样的函数.在这种特定情况下,它们实际上是相似的.

  • 我只会将术语"工厂"用于返回对象的函数. (5认同)

Ber*_*rgi 19

你正在寻找部分申请.它可以用bind例如(或者函数库附带的一些辅助函数,比如Underscore):

arr.map(multiplyBy.bind(null, 4))
Run Code Online (Sandbox Code Playgroud)

但是简单的箭头功能会更容易:

arr.map(x => multiplyBy(4, x))
Run Code Online (Sandbox Code Playgroud)

但是如果你理解你的multiplyBy函数,你可以免费获得部分应用程序,获取乘数并返回一个新函数:

function multiplyBy(multiplier) {
  return function(num) {
    return num * multiplier;
  };
}
// ES6 arrow functions:
const multiplyBy = multiplier => num => num * multiplier;

arr.map(multiplyBy(4));
Run Code Online (Sandbox Code Playgroud)


Phi*_*hil 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
Run Code Online (Sandbox Code Playgroud)