为何遍历嵌套对象键名时for...in循环无法正常工作?
问题排查与解决
你说控制台提示display is not defined,但其实你已经在循环外声明了var display,作用域没问题。真正的bug出在循环里的对象取值逻辑,错误的取值导致代码抛出异常,反而让你误以为是display的问题。
你的代码核心错误
看这段循环代码:
for (let sector in employees) { display = `${sector}: ${employees.engineering.developer[sector].name}`; }
sector遍历的是employees的顶级键:sales和engineering- 但你硬要从
employees.engineering.developer[sector]取值,可developer下面只有frontEndDeveloper和backEndDeveloper,根本没有sales或engineering这两个键,所以这里会先抛出Cannot read properties of undefined (reading 'name')的错误,代码执行中断,才让你产生了display未定义的误解。
针对需求的正确写法
直接获取前端开发人员姓名
如果你只是想拿前端开发的名字,不需要遍历,直接定位取值:
const frontEndName = employees.engineering.developer.frontEndDeveloper.name; console.log(frontEndName); // 输出 John
遍历所有开发人员(前端+后端)
如果要遍历developer下的所有角色:
let display = ''; const devs = employees.engineering.developer; for (let role in devs) { display += `${role}: ${devs[role].name}\n`; } console.log(display); // 输出: // frontEndDeveloper: John // backEndDeveloper: Felix
遍历所有员工姓名(递归处理嵌套对象)
如果想把所有员工的名字都找出来,用递归遍历嵌套对象:
function collectAllNames(obj) { let names = []; for (let key in obj) { // 如果当前对象有name属性,直接收集 if (obj[key].name) { names.push(obj[key].name); } else { // 没有的话递归遍历子对象 names = names.concat(collectAllNames(obj[key])); } } return names; } const allNames = collectAllNames(employees); console.log(allNames); // 输出:["Evan", "Cilian", "Joanna", "Mike", "Amy", "Jenna", "John", "Felix"]
小提示
for...in遍历对象时,要用obj[key]访问动态键对应的属性,不能用obj.key(除非key是固定字符串)- 遍历对象时,建议用
obj.hasOwnProperty(key)过滤原型链上的属性(避免意外遍历到继承的属性)
内容的提问来源于stack exchange,提问作者huz3y
相关产品推荐
相关产品推荐

