如何编写递归JavaScript函数提取嵌套JSON对象的所有键到数组
解决嵌套对象所有键的递归收集问题
问题分析
你需要实现一个递归函数,遍历任意层级的嵌套对象,将所有属性名(键)转换为字符串后收集到数组中返回。针对你提供的示例对象,预期返回结果应为:["OBJECT1", "ATTRIBUTE3", "PARAMETER2", "PROPERTY1"]。
现有代码问题
第一种代码的问题
你的第一个函数逻辑框架正确,但遗漏了当前层级键的收集:当obj[key]是对象时,你只递归收集了子对象的键,却没有把当前的key添加到数组中。此外,空对象不会触发任何分支,导致最底层的键也无法被收集。
第二种代码的问题
第二个函数逻辑混乱且存在多处错误:
- 强制取第一个键的逻辑不通用,无法处理包含多个键的对象
unshift方法返回的是数组新长度,你错误地将其赋值给returnedValue作为递归结果- 返回值类型混用(数字、字符串、数组),导致递归逻辑断裂
正确实现方案
修正后的递归函数
基于你第一个函数的思路,补充当前键的收集逻辑,同时处理空对象、null等边界情况:
function convertKeysToString(obj) { let keys = []; // 过滤非对象和null(typeof null会返回'object') if (typeof obj !== 'object' || obj === null) { return keys; } for (let key in obj) { // 先将当前键转字符串加入数组 keys.push(String(key)); // 若当前值是对象,递归收集子对象的键并合并 if (typeof obj[key] === 'object' && obj[key] !== null) { keys = keys.concat(convertKeysToString(obj[key])); } } return keys; }
更简洁的写法(使用Object.keys)
用Object.keys遍历键,结合flatMap简化递归逻辑:
function getAllNestedKeys(obj) { if (typeof obj !== 'object' || obj === null) return []; return Object.keys(obj).flatMap(key => { // 当前键转字符串,拼接子对象的所有键 return [String(key), ...getAllNestedKeys(obj[key])]; }); }
测试示例
用你的示例对象验证:
const testObj = { OBJECT1: { ATTRIBUTE3: { PARAMETER2: { PROPERTY1: {} } } } }; console.log(convertKeysToString(testObj)); // 输出: ["OBJECT1", "ATTRIBUTE3", "PARAMETER2", "PROPERTY1"]
关键注意点
- 对象判断准确性:必须额外判断
obj !== null,避免typeof null === 'object'的干扰 - 当前键优先收集:无论对应的值是否为对象,当前层级的键都需要先加入数组
- 递归终止条件:当输入不是有效对象时,返回空数组终止递归
内容的提问来源于stack exchange,提问作者Lukáš Schöbel
相关产品推荐
相关产品推荐

