做前端开发或者写接口对接的时候,经常遇到后台返回一长串JSON数据。看着结构规整,真动手取值时才发现,里头套了好几层对象和数组,手动一层层点下去不仅麻烦,还容易出错。这时候就得靠深度遍历,把JSON里的每一个角落都翻个遍。
为什么需要深度遍历?
举个例子,你从服务器拿到一份用户信息,里头除了姓名、邮箱,还有设备列表、登录历史、偏好设置,甚至每个设备又包含型号、系统版本、上次连接时间。这种层层嵌套的结构,想找出所有“iOS”系统的设备,光用 for...in 或 Object.keys() 根本不够用。
深度遍历就是写一段逻辑,自动钻进每一个对象或数组,直到最底层的字符串、数字或布尔值,边走边检查你要的内容。
一个简单的递归函数实现
下面是用 JavaScript 写的一个通用遍历方法,能处理对象和数组混合的情况:
function traverse(obj, callback, path = '') {
if (obj && typeof obj === 'object') {
for (let key in obj) {
const currentPath = path ? `${path}.${key}` : key;
if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
traverse(obj[key], callback, currentPath);
} else if (Array.isArray(obj[key])) {
traverse(obj[key], callback, currentPath);
callback(obj[key], currentPath);
} else {
callback(obj[key], currentPath);
}
}
} else if (Array.isArray(obj)) {
for (let i = 0; i < obj.length; i++) {
const currentPath = `${path}[${i}]`;
if (typeof obj[i] === 'object' && obj[i] !== null) {
traverse(obj[i], callback, currentPath);
} else {
callback(obj[i], currentPath);
}
}
}
}
调用方式也很直接:
const data = {
user: {
name: '张三',
devices: [
{ model: 'iPhone', os: 'iOS' },
{ model: 'Mate 60', os: 'HarmonyOS' }
]
}
};
traverse(data, (value, path) => {
if (value === 'iOS') {
console.log('发现iOS设备:', path);
}
});
// 输出:发现iOS设备: user.devices[0].os
实际应用场景
在安装某些配置复杂的软件时,比如自研的数据中台工具或本地部署的API网关,它的配置文件可能是几十层深的JSON。你不可能肉眼一个个找字段。写个小脚本跑一下,就能快速定位某个参数的位置,或者批量替换测试环境的IP地址。
再比如,导出的用户行为日志是嵌套的JSON数组,你想统计所有点击“购买”按钮的记录,用深度遍历配合关键字匹配,几行代码就能搞定。
注意事项
递归虽然方便,但数据太深可能引发栈溢出。如果遇到特别复杂的结构,可以改用基于栈的迭代方式,避免爆栈。另外,记得判断 null 和 undefined,别让程序中途崩了。
处理JSON不是非得一行行手拆,掌握深度遍历,等于拿到了一把万能钥匙。