任意参数路径

2020-07-28  本文已影响0人  Creator93
输入任意对象,任意参数路径能获取对应的值的 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)
}
上一篇下一篇

猜你喜欢

热点阅读