You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:42:31