如何确定JSON嵌套对象的最大深度?求高效实现方案
计算JSON对象的最大深度:Lodash与原生JS方案
原生JavaScript递归实现(适配你的计数逻辑)
下面的函数会返回对象的嵌套层数(和你示例中的结果一致),同时支持处理数组,还能避免循环引用:
function getMaxNestedDepth(obj, visited = new Set()) { // 非对象/数组、null或已访问过的对象,返回0(无嵌套) if (typeof obj !== 'object' || obj === null || visited.has(obj)) { return 0; } visited.add(obj); // 递归计算每个属性值的嵌套深度,取最大值加1(当前这层嵌套) const depths = Object.values(obj).map(val => getMaxNestedDepth(val, visited)); visited.delete(obj); // 回溯,不影响其他分支的遍历 return depths.length ? Math.max(...depths) + 1 : 0; } // 测试你的示例对象 const testObj = { a: "aVal", b: { b1: "b1Val", b2: "b2Val", b3: { b3a: "b3aVal" } } }; console.log(getMaxNestedDepth(testObj)); // 输出:2
迭代版(避免递归栈溢出,适合超大对象)
如果处理的对象层级极深,递归可能导致栈溢出,这时候可以用广度优先搜索(BFS)的迭代方案:
function getMaxDepthIterative(obj) { if (typeof obj !== 'object' || obj === null) return 0; let maxDepth = 0; const queue = [{ item: obj, depth: 0 }]; const visited = new Set([obj]); while (queue.length > 0) { const { item, depth } = queue.shift(); maxDepth = Math.max(maxDepth, depth); Object.values(item).forEach(val => { if (typeof val === 'object' && val !== null && !visited.has(val)) { visited.add(val); queue.push({ item: val, depth: depth + 1 }); } }); } return maxDepth; } console.log(getMaxDepthIterative(testObj)); // 输出:2
Lodash方案
Lodash没有直接提供计算对象深度的API,但可以结合_.isPlainObject和递归快速实现:
const _ = require('lodash'); function getMaxDepthWithLodash(obj, currentDepth = 0) { // 不是纯对象或数组,返回当前深度 if (!_.isPlainObject(obj) && !Array.isArray(obj)) { return currentDepth; } // 遍历所有属性值,递归计算深度,取最大值 return _.max(_.map(obj, val => getMaxDepthWithLodash(val, currentDepth + 1))) || currentDepth; } console.log(getMaxDepthWithLodash(testObj)); // 输出:2
补充说明
- 以上方案都支持数组嵌套(比如
{ arr: [1, { nested: 2 }] }会返回深度1) visited集合用于避免循环引用导致的无限递归,如果你的JSON对象绝对没有循环引用,可以去掉这个参数简化代码
内容的提问来源于stack exchange,提问作者Ben d'Straw
相关产品推荐
相关产品推荐

