总体结论
我在 GitHub 上打开了一个问题:https://github.com/lodash/lodash/issues/379
感谢jdalton,问题现已解决。示例:→jsFiddle
详细信息(为什么结果“奇怪”?)
我从未详细使用过 Lodash,但以下是我的研究:
检索集合的最大值。如果集合为空或返回虚假-Infinity。
— Lodash Documentation: _.max()
测试_.max() 与每个小组各自完美地工作:
_.max([1,2,3]); // 3
_.max([4,5,6]); // 6
_.max([7,8,9]); // 9
现在,我尝试在_.map()的回调函数中手动调用_.max():
var a = [ [1,2,3], [4,5,6], [7,8,9] ];
alert(_.map( a, function(val) {
return _.max(val);
}));
工作正常!那么这与提供_.max() 作为第二个参数有什么区别呢?
_.map()实际上向回调函数发送了3个参数:
(值,索引|键,集合)。
— Lodash Documentation: _.map()
现在考虑_.max()的第二个参数:
2.[callback=identity] (Function|Object|string):每次迭代调用的函数。如果提供了属性名称或对象,它将是
分别用于创建“.pluck”或“.where”样式的回调。
— Lodash Documentation: _.max()
结论: _.max() 也传递了_.map() 提供的第二个和第三个参数。第二个参数在这里很重要!为它传递真实值(例如整数!= 0)让函数返回-Infinity。
测试用例(→ jsFiddle):
alert(_.max([1,2,3], 0)); // 3
alert(_.max([1,2,3], 1)); // -Infinity
alert(_.max([1,2,3], 2)); // -Infinity
这来自源代码中执行的布尔检查:
https://github.com/lodash/lodash/blob/f0f7eee963966516490eb11232c9e9b4c6d0cc6c/dist/lodash.js#L3431
因为callback(第二个参数)是真值,所以直接跳转到else分支。在那里,callback 被重新分配如下(三元运算也将采用 else 分支):
lodash.createCallback(callback, thisArg, 3);
createCallback() 定义为 here。
它为我们的特定输入参数返回以下函数(这些是1, null, 3,详见_.max()):
return function(object) {
return object[func];
};
假设我们将其保存在一个名为 callback (→ jsFiddle) 的变量中:
var callback = _.createCallback(1, null, 3);
使用 object = 1(或 2、3 或 6 等)调用该函数会得到 undefined(这很明显)。
回到_.max(),我们看到有一个循环将当前 值(来自回调函数)与初始/最后一个值进行比较,即设置为-Infinity在函数的开头。
undefined > -Infinity 永远不会导致 true,因此-Infinity 将保持“最大值”。