为什么我的基于减少的平均函数返回NaN?

Ami*_*ran 5 javascript arrays math prototype

试图获得数组的平均值.

Array.prototype.average = function() {
    var sum = 0;
    this.reduce(function(a, b) {
        sum = a + b;
    });
    return sum / this.length;
};

[2, 15, 7].average();
Run Code Online (Sandbox Code Playgroud)

为什么average函数调用返回NaN

the*_*eye 10

您的程序不起作用,因为,a具有上一个函数调用的累计值.第一次,将使用数组的前两个值.所以sum将成为17(2 + 15).由于您没有从函数返回任何内容,因此undefined默认情况下将返回该值a,并在下次调用中将其用作值.所以,评估是这样的

a: 2,          b: 15   => 17
a: undefined,  b: 7    => NaN
Run Code Online (Sandbox Code Playgroud)

因此,sum将有NaN,因为undefined + 7它是如此.任何数字操作NaN,总是给出NaN,这就是为什么NaN / this.length给你NaN.您可以修复程序,只需返回sum调用函数时的当前值,以便在下一次函数调用时,a将具有适当的累计值.

Array.prototype.average = function() {
    var sum = 0;
    this.reduce(function(a, b) {
        sum = a + b;
        return sum;
    });
    return sum / this.length;
};
Run Code Online (Sandbox Code Playgroud)

但我们并没有充分利用reduce这里的力量和灵活性.以下是使用时需要考虑的两个要点reduce.

  1. reduce接受第二个参数,该参数表示要使用的初始值.只要有可能,请指定.

  2. 函数中的第一个参数用于reduce累积结果并最终返回,使用它.无需使用单独的变量来跟踪结果.

所以你的代码看起来会更好

Array.prototype.average = function() {

    var sum = this.reduce(function(result, currentValue) {
        return result + currentValue
    }, 0);

    return sum / this.length;

};

console.log([2, 15, 7].average());
# 8
Run Code Online (Sandbox Code Playgroud)

reduce实际上是这样的.它遍历数组并将当前值作为第二个参数传递给函数,当前累计结果作为第一个参数传递,函数返回的值将存储在累计值中.所以,总和实际上是这样找到的

result: 0 , currentValue: 2   => 2    (Initializer value `0`)
result: 2 , currentValue: 15  => 17
result: 17, currentValue: 7   => 24
Run Code Online (Sandbox Code Playgroud)

由于它耗尽了数组中的值,24因此将返回结果reduce,将其存储sum.


Ant*_*ala 6

您的匿名添加函数不返回任何值,reduce适用于返回值的函数:

尝试:

Array.prototype.average = function() {
    var sum = this.reduce(function (a, b) {
        return a + b;
    }, 0);
    return sum/this.length;
};
Run Code Online (Sandbox Code Playgroud)

另一种可能性是您的数组包含字符串而不是数字,因此您可能希望将它们强制转换为数字return (+a) + (+b); 因为如果你有"10.0""20.0",加在一起给人"10.020.0",其除以任意数量再次给出NaN.