13

我正在尝试一个明显的任务:

var maxVal = [ 1, 2, 3, 4, 5 ].reduce( Math.max, 0 );

并得到:

NaN

作为结果。为了使它工作,我必须以这种方式创建一个匿名函数:

var maxVal = [ 1, 2, 3, 4, 5 ].reduce( function ( a, b ) { 
                                           return Math.max(a, b);
                                       }, 0 );

有人能告诉我为什么吗?两者都是接受两个参数并且都返回一个值的函数。有什么不同?

另一个例子可能是这样的:

var newList = [[1, 2, 3], [4, 5, 6]].reduce( Array.concat, [] );

结果是:

[1, 2, 3, 0, #1=[1, 2, 3], #2=[4, 5, 6], 4, 5, 6, 1, #1#, #2#]

我只能在这个形状下在 node.js 中运行这个示例(数组在 node.js v4.12 中没有 concat,我现在使用它):

var newList = [[1, 2, 3], [4, 5, 6]].reduce( [].concat, [] );    

然后得到这个:

[ {}, {}, 1, 2, 3, 0, [ 1, 2, 3 ], [ 4, 5, 6 ], 4, 5, 6, 1, [ 1, 2, 3 ], [ 4, 5, 6 ] ]

那为什么呢?

4

3 回答 3

24

传递给的函数reduce 接受超过 2 个参数

  • previousValue
  • currentValue
  • index
  • array

Math.max将评估所有参数并返回最高值:

Math.max(1, 2, 3, 4) === 4;

因此,在传递Math.maxto的情况下reduce,它将返回传递的 4 个参数中的最大值,其中一个是数组。传递数组将Math.max返回NaN,因为数组不是数字。这是规范(15.8.2.11):

给定零个或多个参数,对每个参数调用 ToNumber 并返回结果值中的最大值。

...

如果任何值为 NaN,则结果为 NaN

ToNumber将返回NaN一个数组。

所以减少 withMath.max最终会返回NaN

于 2011-10-14T12:46:00.927 回答
4

由于Math.max接受多个参数,您可以通过apply函数将数组转换为参数列表。

var maxVal = Math.max.apply(Math, [ 1, 2, 3, 4, 5 ]);

请参阅此处有关此技术限制的警告。

于 2011-10-14T13:14:05.420 回答
3

另一种将数组减少到最大值的方法:

var maxVal = [ 1, 2, 3, 4, 5 ].reduce(function(a,b){return a>b?a:b});

(说明 reduce 的工作原理,并不是说它是从数组中获取最大数的最佳方法)

于 2011-10-14T12:52:46.740 回答