向嵌套数组push新子数组后读取子数组length返回undefined是什么原因?
问题分析
- 报错根因:你访问
payrollDb[i].length时报错,说明payrollDb数组中存在非数组类型的元素(比如undefined、null、普通字符串/数字等),你本次push的子数组是正常的,但遍历到之前存入的非数组元素时,访问.length属性就会抛出该错误。 - 查重逻辑错误:现有代码的三元表达式会每次循环都覆盖
result的值,即使前面已经匹配到了重复ID,只要后面有一个元素不匹配,result就会被改写为false,最终只有数组最后一个元素匹配时才会判定为重复,完全不符合查重需求。 - 测试逻辑不合理:函数内每次执行都主动push新的submissionId到数据库,正式运行时会导致只要调用该函数就会新增一条无效记录,后续查重永远会返回重复,该测试代码建议迁移到函数外或者测试完成后删除。
修复方案
推荐用更简洁的数组原生方法实现,同时兼容异常情况避免报错:
function checkDupe(submissionId) { // 兼容payrollDb未初始化的情况 if (!Array.isArray(payrollDb)) payrollDb = []; // 嵌套查重:只要任意子数组中存在目标ID就判定为重复 const isDuplicate = payrollDb.some(subItem => { // 跳过非数组类型的异常元素,避免报错 if (!Array.isArray(subItem)) return false; return subItem.includes(submissionId); }); return isDuplicate ? views_payroll_duplicate : views_payroll_period; }
兼容旧for循环的修复版本
如果你更习惯用for循环的写法,可以加类型判断和提前终止逻辑优化:
function checkDupe(submissionId) { let isDuplicate = false; if (!Array.isArray(payrollDb)) payrollDb = []; for (let i = 0; i < payrollDb.length; i++) { const currentSub = payrollDb[i]; // 跳过非数组元素 if (!Array.isArray(currentSub)) continue; for (let j = 0; j < currentSub.length; j++) { if (currentSub[j] === submissionId) { isDuplicate = true; // 匹配到直接跳出两层循环,无需继续遍历 break; } } if (isDuplicate) break; } return isDuplicate ? views_payroll_duplicate : views_payroll_period; }
内容的提问来源于stack exchange,提问作者Mike Budgell
相关产品推荐
相关产品推荐

