JS遍历数组访问对象属性报Cannot read properties of undefined
问题排查记录
已实现功能
score(start, end, step):生成指定数值区间、指定步长的随机数,用于生成科目分数generateStudents(nameArr):接收姓名数组,返回学生对象列表,单个学生对象结构为{"name": 姓名, "marks": {各科目分数}}findStudentMinMax():待实现的分数极值学生查找函数,当前运行报错
报错信息
执行代码时抛出异常:Cannot read properties of undefined (reading 'name')
完整复现代码
var score = function getRandomMark(start, end, step) { var num = start var arr = [] arr.push(num) while (num <= (end - step)) { num += step arr.push(num) } var index = Math.floor(Math.random() * (arr.length)) return (arr[index]) } var generateStudents = function generateStudent(nameArr) { var studentArr = [] for (let i = 0; i < nameArr.length; i++) { var student = { "name": nameArr[i], "marks": { "literature": score(6, 10 , 0.5), "maths": score(6, 10 , 0.5), "chemistry": score(6, 10 , 0.5), "history": score(6, 10 , 0.5), "biology": score(6, 10 , 0.5) } } studentArr.push(student) } return studentArr } var markList = ["Chi", "Duc", "Huy"] var findStudentMinMax = function findStudentMinMax() { var obj = generateStudents(markList) console.log(typeof (obj)) var obj1 = {} var obj2 = {} var arr1 = [] var arr2 = [] const keys1 = Object.keys(obj[0]["marks"]) for (let i = 0; i < keys1.length; i++) { var name = obj[i].name console.log(obj[i]) } } findStudentMinMax()
根因分析
数组索引越界:
- 变量
keys1是第一个学生的科目键列表,长度为5(对应5门考试科目) - 变量
obj是generateStudents返回的学生数组,传入的姓名列表长度为3,因此obj长度为3,有效索引范围是0、1、2 - 现有for循环以
keys1.length(值为5)作为循环终止条件,当i递增到3、4时,obj[3]、obj[4]不存在,值为undefined,访问undefined的name属性就会抛出题目中的错误。
修复方案
根据遍历目标调整循环终止条件:
- 如果循环目标是遍历所有学生,将循环条件改为学生数组的长度即可:
// 遍历学生的正确写法 const keys1 = Object.keys(obj[0]["marks"]) for (let i = 0; i < obj.length; i++) { var name = obj[i].name console.log(obj[i]) }
- 如果循环目标是遍历所有科目,不要在该循环内通过
i取学生对象,需要将学生遍历和科目遍历拆分为两层循环,避免索引用错。
内容的提问来源于stack exchange,提问作者linhcheee
相关产品推荐
相关产品推荐

