输入任意对象,任意参数路径能获取对应的值的 js 函数
遇到这个题最后想法就是 使用正则获取加验证 结合reduce 去实现,通过调试实现了下,同时也包含了遇到match 匹配 小括号不匹配的缺陷时,重写/g execAll方法来手动捕获
function safeAccessObj(obj, ...args) {
if(!obj) return null;
let result = []
let reg = /([a-zA-Z_$]+[a-zA-Z_$0-9]*)|\[([0-9]+)\]*/g;
args.forEach(item=> {
let arr = execAll(reg, item)
let t = arr.reduce((pre, cur) => {
if(typeof pre !== 'object') return pre;
if(cur.indexOf('[') !==-1) {
// return pre[cur.replace(/\[([0-9]+)\]/, "$1")]
return eval(`pre${cur}`)
} else {
return pre[cur];
}
},obj)
result.push(t)
})
return result;
// path.replace(/[a-zA-Z]+|\[([0-9]+)\]/g, (a, b) => {console.log(b)})
// 'a.b.c[9].d[33]'.replace(/([a-zA-Z]+)|\[([0-9]+)\]/g, (a, b,c) => {console.log(a, '-',b,c)})
}
console.log(safeAccessObj({"a":{"b":{"c":[0,1,{"d":"hahha"},3,{"name":"name000"}]},"m":"dsafads"}}, 'a.b.c[2].d', 'a.m'))
// console.log(safeAccessObj({a:{b:{c:[0,1,{d:'hahha'},3,{name:'name000'}]}}}, 'a.b.c'))
function execAll(reg, str) {
let arrRes = [];
let res = reg.exec(str)
while(res) {
let [big, ] = res
arrRes.push(big)
res = reg.exec(str)
}
return arrRes
}
直接使用模板字符串的方式,不能安全检查
// 输入任意对象,任意参数路径能获取对应的值的 js 函数
get(obj, 'selector.to.toutiao', 'target[0]', 'target[2].name')
var obj = {
selector: {
to: { toutiao: "FE Coder"}
},
target: [
1,
2,
{ name: 'byted' }
]
};
function get(data, ...args) {
const res = JSON.stringify(data);
var a = args.map((item) => (new Function(`return ${res}.${item} `))());
console.log(a)
}
网友评论