JavaScript:将属性访问器字符串转换为实际属性取值方式
如何将混合点表示法与方括号的属性访问器字符串转换为实际属性访问链?
问题场景
给定如下JavaScript对象:
const person = { name: 'David', locations: [ { country: 'Belgium', }, { country: 'France', }, { country: 'Ireland', }, ], };
现在持有类似 "person.locations[0].country" 这种混合了点表示法与方括号表示法的属性访问器字符串,需要将其转换为可直接获取对应属性值的访问逻辑。
解决方案
1. 手动解析路径(安全通用)
自己实现解析函数,拆分路径片段后逐个访问属性,避免安全风险,同时兼容各种边界情况:
function getProperty(obj, path) { // 拆分路径:处理点、方括号分隔符,过滤空片段 const parts = path.split(/[\.\[\]]/).filter(part => part.trim() !== ''); let current = obj; for (const part of parts) { // 判断是否为数组索引 const index = parseInt(part, 10); current = isNaN(index) ? current[part] : current[index]; // 中途遇到null/undefined直接返回,防止报错 if (current == null) return undefined; } return current; } // 使用示例 console.log(getProperty(person, 'person.locations[0].country')); // 输出 'Belgium' console.log(getProperty(person, 'person.locations[2].country')); // 输出 'Ireland' console.log(getProperty(person, 'person.age')); // 输出 undefined
2. 使用Function构造函数(仅适用于可信路径)
如果能确保路径字符串是完全可信的(比如内部生成,无用户输入),可以用Function动态生成访问逻辑,代码更简洁:
function getPropertyByFunction(obj, path) { // 移除路径开头的对象名前缀(比如示例中的'person.') const cleanPath = path.replace(/^[a-zA-Z_$][a-zA-Z0-9_$]*\./, ''); const func = new Function('obj', `return obj.${cleanPath};`); return func(obj); } // 使用示例 console.log(getPropertyByFunction(person, 'person.locations[0].country')); // 输出 'Belgium'
注意:这种方法存在安全风险,如果路径包含恶意代码,会导致代码注入,禁止用于处理不可信的用户输入。
3. 借助第三方库(如Lodash)
如果项目中已经引入了Lodash,可以直接使用它的_.get方法,原生支持混合格式的路径,同时内置了边界处理:
// 先确保已引入Lodash // import _ from 'lodash'; console.log(_.get(person, 'locations[0].country')); // 输出 'Belgium' // 可以指定属性不存在时的默认值 console.log(_.get(person, 'person.age', '未知')); // 输出 '未知'
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

