JavaScript获取对象所有可访问属性完整路径需递归遍历+路径拼接+状态跟踪:对对象用for...in,数组用索引方括号;合法标识符用点号,否则用方括号;WeakMap防循环引用;支持过滤、非枚举属性及多种返回格式。

要获取 JavaScript 对象中所有可访问属性的完整路径(如 "user.profile.name" 或 "items[0].id"),并支持嵌套对象、数组、循环引用防护,核心在于递归遍历 + 路径拼接 + 状态跟踪。
基础递归遍历:处理对象与数组
普通对象和数组是递归主干。对每个键/索引,生成新路径,再对其值递归调用:
- 对象:用
for...in或Object.keys()遍历自有可枚举属性 - 数组:用
Array.isArray()判断,对每个索引i构建路径path + '[' + i + ']' - 基础类型(string/number/boolean/null/undefined)直接记录路径,停止递归
路径格式化:点号 vs 方括号,兼顾可读性与合法性
路径应能准确还原访问方式,同时尽量简洁可读:
- 对象属性名满足标识符规则(如
name、firstName)→ 用点号:"user.name" - 含空格、特殊字符、数字开头或保留字(如
"first name"、"123id"、"class")→ 用方括号:"user['first name']" - 数组索引统一用方括号:
"list[0].value" - 避免重复转义,不手动拼接
eval或Function字符串
安全防护:检测并跳过循环引用
若对象存在自引用(如 obj.parent = obj),不加控制会导致栈溢出。需记录已访问对象的引用:
立即学习“Java免费学习笔记(深入)”;
- 使用
WeakMap存储object → path映射(键为对象引用,不阻止 GC) - 每次进入新对象前,检查是否已在 WeakMap 中;若存在,跳过该分支并可选记录警告路径(如
"a.b.c → a") - 注意:不能用 JSON.stringify 检测,因它本身会报错且无法获取路径
实用增强:过滤、类型控制与结果组织
生产环境常需定制行为:
- 支持传入
filter函数,按路径或值类型排除项(如忽略函数、Symbol、undefined) - 提供
includeNonEnumerable: true选项,用Object.getOwnPropertyNames()+Object.getOwnPropertySymbols()补充遍历 - 返回结构可选:扁平路径数组、树形嵌套对象、或带值的键值对数组
[{ path: 'x.y', value: 42 }] - 对
Date、RegExp、Map、Set等内置类型,按需决定是否展开或视为叶子节点
不复杂但容易忽略细节——路径合法性判断、循环引用标记、数组与对象语法差异,三者缺一不可。实现时优先保证健壮性,再叠加可配置能力。










