如何判断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
相关产品推荐
相关产品推荐

