JavaScript reduce无法处理数学函数?

时间:2011-10-14 12:41:24

标签: javascript node.js reduce higher-order-functions

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

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中运行这个例子(Array在node.js v4.12中没有连接,我现在使用它):

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 ] ]

为什么会这样?

3 个答案:

答案 0 :(得分:19)

传递给reduce takes more than 2 arguments的函数:

  • previousValue
  • currentValue
  • index
  • array

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

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

因此,如果将Math.max传递给reduce,它将从传递的4个参数中返回最高值,其中一个是数组。传递数组会使Math.max返回NaN,因为数组不是数字。这是规格(15.8.2.11):

  

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

     

...

     

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

ToNumber将返回NaN数组。

因此,使用Math.max缩减最终会返回NaN

答案 1 :(得分:4)

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

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

See warnings here关于这种技术的局限性。

答案 2 :(得分:2)

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

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

(说明减少如何工作,而不是从数组中获取最大数量的最佳方法)