JavaScript reduce无法处理数学函数?

trz*_*zek 13 javascript reduce node.js higher-order-functions

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

var maxVal = [ 1, 2, 3, 4, 5 ].reduce( Math.max, 0 );
Run Code Online (Sandbox Code Playgroud)

得到:

NaN
Run Code Online (Sandbox Code Playgroud)

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

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

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

另一个例子可能是:

var newList = [[1, 2, 3], [4, 5, 6]].reduce( Array.concat, [] );
Run Code Online (Sandbox Code Playgroud)

结果是:

[1, 2, 3, 0, #1=[1, 2, 3], #2=[4, 5, 6], 4, 5, 6, 1, #1#, #2#]
Run Code Online (Sandbox Code Playgroud)

我只能在这个形状下在node.js中运行这个例子(Array在node.js v4.12中没有连接,我现在使用它):

var newList = [[1, 2, 3], [4, 5, 6]].reduce( [].concat, [] );    
Run Code Online (Sandbox Code Playgroud)

然后得到这个:

[ {}, {}, 1, 2, 3, 0, [ 1, 2, 3 ], [ 4, 5, 6 ], 4, 5, 6, 1, [ 1, 2, 3 ], [ 4, 5, 6 ] ]
Run Code Online (Sandbox Code Playgroud)

那为什么呢?

pim*_*vdb 22

传递的函数reduce 需要超过2个参数:

  • previousValue
  • currentValue
  • index
  • array

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

Math.max(1, 2, 3, 4) === 4;
Run Code Online (Sandbox Code Playgroud)

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

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

...

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

ToNumber将返回NaN一个数组.

因此减少Math.maxNaN最终返回.

  • 另一种解决方案可以是:Math.max.apply(null,[1,2,3,4,5]); (2认同)