Javascript 减少未定义的返回?

Javascript 减少未定义的返回?,javascript,Javascript,我有一个名为student的对象,它有两个属性,name和score。我试图使用score属性执行计算,但从学生数组访问属性时遇到问题。目前,我正在尝试使用以下代码获取分数总和: var sum = students.reduce(function(a, b) { return {sum: a.score + b.score} }) 这将返回一个未定义的值,并导致firefox中的显示异常。我似乎找不到错误 是否

我有一个名为student的对象,它有两个属性,name和score。我试图使用score属性执行计算,但从学生数组访问属性时遇到问题。目前,我正在尝试使用以下代码获取分数总和:

var sum = students.reduce(function(a, b) { 
                    return {sum: a.score + b.score}
                    })
这将返回一个未定义的值,并导致firefox中的显示异常。我似乎找不到错误


是否没有办法简单地访问参数(即,
var myVar=myArray.myObject.myProperty;
)?

我认为您对如何工作存在误解。对于数组中的每个元素,它执行提供的函数。第一个参数是“累加器”;访问每个元素时传递的内容(实际上,它是最后一个元素的函数返回值,但通常用作累加器)。第二个参数是正在访问的元素。所以我想你想要的是:

var sum = students.reduce(function(a, s) {
    a.sum += s.score;
    return a;
}, { sum: 0 });
调用
reduce
时,您可以提供累加器的初始值(否则它接受第一个元素的值,访问从第二个元素开始)。在这里,我们提供了一个
sum
属性设置为零的对象

如果您只需要sum(而不是具有
sum
属性的对象),那么它可以更简单:

var sum = students.reduce(function(a, s) {
    return a += s.score;
}, 0);

<> >在尼格买提·热合曼对 Reals的充分解释中,您也可以将<代码> map <代码>考虑为适当的格式,以将其简化为单个值。

students.map( student => student.score ).reduce( (a, b) => a + b, 0 );

您的代码没有任何一点调试无法解决的问题。在
return
语句上放置一个断点。当发动机停在那里时,检查
a
b
的值。或者,正如评论员所建议的,您可以在那里添加
console.log
行,以将值输出到控制台。在任何一种情况下,您都会看到它们是数组中的前两个值——如果您没有给它第二个参数,
reduce
就是这样工作的。返回的值将是
{sum:students[0]。score+students[1]。score}
。现在继续执行。您将在
return
语句处再次中断;再次检查
a
b
。您将看到
a
不是学生,也不是数字,而是在上一次迭代中返回的
{sum:}
对象,它没有
score
属性。假设前两个分数之和为192,那么下一个返回值将是
{sum:{sum:192}。score+students[2]。score}
。这就变成了
{sum:undefined+students[2].score}
,这又变成了
NaN
,因为向
undefined
添加任何内容都会返回
NaN
。现在事情从那里开始走下坡路

当你第二次在循环中发现,
a
{sum:192}
,你应该意识到这既不是一个你可以拿分数的学生,也不是一个你可以增加分数的学生。再阅读一下
reduce
文档,也许再看几个例子,您应该能够弄清楚您需要返回的是sum本身,而不是包含属性
sum
的对象。然后,该总和将在循环的下一次迭代中成为
a
。要使其工作,您需要为
reduce
提供一个初始值0作为其第二个参数


当你继续你的编程之旅时,你会遇到很多这样的坎坷。不幸的是,你不能指望这么多人帮你解决所有问题,即使他们解决了,你也可能会被困数小时或数天,直到他们回答。你真的需要学会如何自己解决这些问题。调试器是实现这一点的关键,因此除了学习如何启动调试器、设置断点和检查变量外,别无选择。从你的日程中抽出几个小时,仔细阅读文档。你可以在。下面是如何调试小程序的一个很好的概述

第二次调用回调时,
a
将是先前返回的对象,并且该对象没有
score
属性。(回调中的一些console.log()语句应该会向您显示问题…)在第二个示例中,请确保我正确理解了语法。a是累加器吗?你说这是一个返回值,但如果它们都是单独定义的,它们不是不同的东西吗?无论哪种方式,a都保存当前值。s是数组元素,在本例中是每个student对象,因此s.score是student.score。我不确定+=是什么,但一旦我查过它,它就足够明显了,直到现在才需要使用它,0); 零是什么意思?如果它是var sum的初始值,为什么我们需要它,未初始化的默认值不起作用吗?@SpaceOstrich第一个参数是累加器,无论它是一个运行总数,还是一个当前的最大/最小值,或者是一个要添加内容的对象,或者一个数组,它都会累加正在运行的操作的返回值,和等于上一个返回值。至于“为什么是0”,如果
reduce
没有给出默认值,并且数组中有多个元素,那么第一次运行
reduce
arr[0]用作a,将arr[1]用作b
。在您的例子中,在使用
map
对其进行变换之前,您可以看到这将如何导致需要检查
a
是否是一个形状或另一个形状的问题。我喜欢使用变量的相同名称调用“累加器”。这有助于理解发生了什么。使用ESNext的示例:
let sum=students.reduce((sum,student)=>{…},init)我喜欢这种方法,@rafaelbiten,当我的累加器很简单时,比如
sum
max
或其他什么,我经常使用它。但有时这是一件复杂的事情:就像一个我