为什么我的基于约简的平均值函数返回 NaN
Why does my reduce based average function return NaN?
试图获取数组的平均值。
Array.prototype.average = function() {
var sum = 0;
this.reduce(function(a, b) {
sum = a + b;
});
return sum / this.length;
};
[2, 15, 7].average();
为什么average
函数调用返回NaN
?
您的程序不起作用,因为a
具有上一个函数调用的累积值。第一次,将使用数组的前两个值。所以sum
会变得17
(2 + 15
(。由于您没有从函数返回任何内容,因此默认情况下将返回undefined
,并且在下一次调用中将用作 a
的值。所以,评估是这样的
a: 2, b: 15 => 17
a: undefined, b: 7 => NaN
所以,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;
};
但是,我们在这里没有利用reduce
的力量和灵活性。以下是使用reduce
时要考虑的两个要点。
reduce
接受第二个参数,该参数表示要使用的初始值。尽可能指定。传递给
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
reduce
实际上是这样工作的。它遍历数组并将当前值作为第二个参数传递给函数,将当前累积结果作为第一个参数传递给函数,从函数返回的值将存储在累积值中。所以,总和实际上是这样找到的
result: 0 , currentValue: 2 => 2 (Initializer value `0`)
result: 2 , currentValue: 15 => 17
result: 17, currentValue: 7 => 24
由于数组中的值用完了,24
将作为reduce
的结果返回,该结果将存储在 sum
中。
您的匿名加法函数不返回任何值,reduce
处理返回值的函数:
尝试:
Array.prototype.average = function() {
var sum = this.reduce(function (a, b) {
return a + b;
}, 0);
return sum/this.length;
};
另一种可能性是你的数组包含字符串而不是数字,因此你可能想用return (+a) + (+b)
强迫它们为数字;就像你有"10.0"
和"20.0"
一样,将它们加在一起得到"10.020.0"
,再次除以任何数字得到NaN
。
您已经有了其他人提供的问题的答案,但我想我只是用一个例子来扩展我的评论。
if (!Array.prototype.average) {
Object.defineProperty(Array.prototype, 'average', {
value: function () {
if (typeof this === 'undefined' || this === null) {
throw new TypeError('Cannot convert argument to object');
}
var object = Object(this);
return [].reduce.call(object, function (result, currentValue) {
return +(currentValue) + result;
}, 0) / object.length;
}
});
}
var out = document.getElementById('out');
out.textContent += [2, 15, 7].average() + ''n';
out.textContent += [].average.call({
0: '2',
1: '15',
2: '7',
length: 3
}) + ''n';
out.textContent += [].average.call('123') + ''n';
<pre id="out"></pre>
无论从reduce返回什么值,它都会成为下一次调用中的第一个参数,因此您必须返回一些内容。此外,如果您有意扩展原型,请确保首先检查是否存在,这样您就不会覆盖其他人的方法。
无需在函数体中创建任何其他变量,因为它都可以在一行中实现。
if(!Array.prototype.average) {
Array.prototype.average = function() {
return this.reduce(function(a, b){ return a + b; }) / this.length;
};
}
另请注意,reduce的第二个参数在对数字求和时不是很有用,除非您尝试从零以外的数字求和,而零并不完全对一组数字求和。
还有更多关于MDN的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
- ES6构造函数返回基类的实例
- 从函数返回角度承诺
- 如何从jquery函数返回变量
- 根据是否解析了 Promise 从函数返回值
- Javascript函数返回未定义
- 如果函数返回True,则显示Javascript按钮
- Google Sheet自定义函数返回0
- 从Ajax函数返回值
- 使用for循环从Javascript中的函数返回多个值
- 谷歌地图:函数返回未定义的值在console.log中运行良好
- 从函数中的函数返回数组时出错
- 如何从嵌套的API函数返回值
- 从Mongoose结果匿名函数返回父函数
- 函数返回错误'令牌{'
- Jquery函数返回订单问题
- Mocha/Chai测试链接到函数返回断言错误
- 从异步函数返回值
- 函数返回后更新变量
- 我如何才能继续'如果'语句来比较作为参数的多个函数返回值
- 将外部函数返回的id传递给内部函数