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

如何判断JS对象属性为最终值或嵌套对象并获取全路径属性

嵌套对象最终层级属性遍历方案

节点类型判断规则

要区分最终属性值和嵌套子对象,不能直接用typeof value === 'object'判断,要排除JS里的特殊值场景,结合给出的配置对象结构(数组为最终配置值,不需要继续下钻),判断逻辑如下:

  • 符合以下任意条件的属性值,判定为最终层级属性,直接收集:
    • 值为基础类型:字符串、数字、布尔值、函数、Symbol、undefined等
    • 值为null(typeof null返回'object',属于JS历史遗留问题,需要单独排除)
    • 值为数组类型(当前场景下数组是完整配置项,不需要拆分遍历内部元素)
  • 剩余的纯普通对象,判定为嵌套子对象,拼接当前属性名到路径后,继续向下递归遍历。

递归实现代码

function getAllLeafProps(obj, parentPath = '') {
  const result = []
  for (const key of Object.keys(obj)) {
    const value = obj[key]
    // 拼接当前属性的完整访问路径
    const currentPath = parentPath ? `${parentPath}.${key}` : key
    // 校验是否为最终值
    const isLeaf = typeof value !== 'object' || value === null || Array.isArray(value)
    if (isLeaf) {
      result.push({ path: currentPath, value })
    } else {
      // 递归遍历子对象,合并结果
      result.push(...getAllLeafProps(value, currentPath))
    }
  }
  return result
}

// 测试用目标对象
const target = {
  extend: {
    colors: {
      primary: {
        DEFAULT: "#C5003E",
        dark: "#A20033",
      },
      secondary: {
        100: "#F7F8F8",
        300: "#E6E7E9",
        500: "#888888",
        700: "#444444",
        900: "#222222",
      },
      success: "#008540",
      warning: "#EB5A2D",
      gray: {
        DEFAULT: "#444444",
        light: "#888888",
        dark: "#222222",
      },
      veryLightGray: "#E6E7E9",
      background: "#F8F8F8",
    },
    dropShadow: {
      lower: "0 2px 4px rgba(34,34,34,0.1)",
      higher: "0 4px 20px rgba(34,34,34,0.1)",
    },
    fontSize: {
      "bo-xs": ["0.75rem", { lineHeight: "1.25rem" }],
      "bo-sm": ["0.875rem", { lineHeight: "1.375rem" }],
      "bo-base": ["1rem", { lineHeight: "1.5rem" }],
      "bo-lg": ["1.125rem", { lineHeight: "1.625rem" }],
      "bo-xl": ["1.375rem", { lineHeight: "1.875rem" }],
      "bo-2xl": ["1.75rem", { lineHeight: "2.25rem" }],
      "bo-3xl": ["2.25rem", { lineHeight: "2.75rem" }],
    },
    fontFamily: {
      base: ['"Open Sans"', "serif"],
      value: ["Value"],
      valueBold: ["ValueBold"],
    },
    spacing: {
      xxs: "0.25rem",
      xs: "0.5rem",
      sm: "0.75rem",
      md: "1rem",
      lg: "1.5rem",
      xl: "2rem",
      xxl: "3rem",
    },
    borderWidth: {
      1: "1px",
      3: "3px",
      6: "6px",
    },
    boxShadow: {
      base: "0px 3px 17px #2C282820",
      input: "0px 0 5px 0px rgba(0, 0, 0, 0.16)",
      full: "0 5px 16px 0 rgba(0, 0, 0, 0.08)",
      levelRing: "0 0 15px 0 #4ecb7180",
    },
  }
}

// 执行获取所有属性
console.log(getAllLeafProps(target))

输出示例

函数返回的结果是数组,每个元素包含完整访问路径和对应值,部分输出项如下:

[
  { path: 'extend.colors.primary.DEFAULT', value: '#C5003E' },
  { path: 'extend.colors.primary.dark', value: '#A20033' },
  { path: 'extend.colors.success', value: '#008540' },
  { path: 'extend.fontSize.bo-xs', value: ["0.75rem", { lineHeight: "1.25rem" }] },
  { path: 'extend.spacing.md', value: '1rem' },
  // ...其余所有最终属性
]

如果后续需要调整遍历规则,比如要继续拆分数组内部的对象、或者要排除某些特定key,直接修改isLeaf的判断条件、或者在遍历key时加过滤逻辑即可。

内容的提问来源于stack exchange,提问作者juzello

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:21:31