JavaScript如何实现showPath方法获取嵌套对象的级联键路径
问题说明
现有如下JavaScript对象:
thing1 = {'fp1': [{'dp1a': 0}, {'dp1b': 1}], 'fp2': [{'dp2a': 2}, {'dp2b': 3}]}
需要编写showPath()方法,满足如下调用规则:
thing1.fp1.dp1a.showPath()
方法需要返回调用对象对应的级联键名,上述示例预期返回按层级排列的三个键名:thing1、fp1、dp1a。
实现方案
核心逻辑是用Proxy代理属性访问,每访问一层属性就自动记录当前路径,同时兼容数组穿透逻辑(匹配示例中跳过数组索引直接访问数组内对象属性的写法),给所有层级的值挂载showPath方法返回最终路径。
完整代码
// 存储根对象和对应变量名的映射 const rootMap = new WeakMap(); rootMap.set(thing1, 'thing1'); // 递归给值挂载showPath方法,记录当前路径 function attachShowPath(value, currentPath) { // 基础类型值做包装,支持挂载方法 if (typeof value !== 'object' || value === null) { const wrapper = Object(value); wrapper.showPath = () => currentPath.split('.').filter(Boolean); return wrapper; } // 已经处理过的对象直接返回,避免重复代理 if (value.__pathInited) return value; value.__pathInited = true; value.showPath = () => currentPath.split('.').filter(Boolean); // 代理属性访问,自动传递路径 return new Proxy(value, { get(target, prop) { // 内部属性和showPath方法直接返回 if (prop === 'showPath' || prop === '__pathInited') { return target[prop]; } let childVal = target[prop]; let childPath; // 数组穿透:访问数组不存在的属性时,遍历数组项找对应属性,跳过数组索引 if (Array.isArray(target) && !(prop in target)) { for (const item of target) { if (item && typeof item === 'object' && prop in item) { childVal = item[prop]; childPath = `${currentPath}.${prop}`; break; } } } else { // 常规属性拼接路径,数组索引用[]格式 childPath = Array.isArray(target) ? `${currentPath}[${String(prop)}]` : `${currentPath}.${String(prop)}`; } return attachShowPath(childVal, childPath); } }); } // 初始化根对象 thing1 = attachShowPath(thing1, rootMap.get(thing1));
效果验证
// 题目示例调用 console.log(thing1.fp1.dp1a.showPath()); // 输出: ['thing1', 'fp1', 'dp1a'] console.log(thing1.fp2.dp2b.showPath()); // 输出: ['thing1', 'fp2', 'dp2b'] // 也支持常规带数组索引的访问 console.log(thing1.fp1[1].dp1b.showPath()); // 输出: ['thing1', 'fp1', '1', 'dp1b']
如果需要返回拼接好的路径字符串而不是键名数组,把两处showPath的返回值从currentPath.split('.').filter(Boolean)改成currentPath即可。
内容的提问来源于stack exchange,提问作者Domyno
相关产品推荐
相关产品推荐

