Javascript 如何在不使用多个括号的情况下使用字符串从对象中获取嵌套值?
换言之,我可以这样做:Javascript 如何在不使用多个括号的情况下使用字符串从对象中获取嵌套值?,javascript,Javascript,换言之,我可以这样做:obj['data.users.admins.dashboard[3]] 我可以创建一个简单的函数并解析字符串,然后调用对象。但我想知道什么是可能的,因为会有很多边缘的情况,不平凡的 以上内容与 obj['data']['users']['amdins']['dashboard'][3]您可以使用lodash get 使用eval是可能的,但是eval是邪恶的。使用它的风险自负 const data={users:{admins:{dashboard:[1,2,3,4]};
obj['data.users.admins.dashboard[3]]
我可以创建一个简单的函数并解析字符串,然后调用对象。但我想知道什么是可能的,因为会有很多边缘的情况,不平凡的
以上内容与
obj['data']['users']['amdins']['dashboard'][3]
您可以使用lodash get
使用
eval
是可能的,但是eval
是邪恶的。使用它的风险自负
const data={users:{admins:{dashboard:[1,2,3,4]};
eval('data.users.admins.dashboard[3]”);
通过巧妙地使用split()
和reduce()
,您可以很容易地做到这一点:
constobj={data:{users:{admins:{dashboard:[1,2,3,4]};
常量路径='data.users.admins.dashboard[3];
const result=path.replace(/\[/g',')。replace(/\]/g',)。split('.'))
.reduce((obj,key)=>obj&&obj[key],obj);
控制台日志(结果)代码>您可以使用代理
:
const obj = new Proxy({
data: {
users: {
admins: {
dashboard: [10, 21, 31, 41],
}
}
},
}, {
get: function (map, key, receiver) {
try {
return eval(`map.${key}`)
} catch (error) {
return undefined;
};
},
});
obj['data.users.admins.dashboard[3]'] // 41
obj['erter.sdfdsfds.admins.sdfsdf[3]'] // undefined
在普通对象中,它会抛出一个错误,无法读取undefined==的属性,比js中的常规对象要好:)
更新:
它可以工作,但是并不完美,尤其是嵌套数组无法工作b/c即使是人也不知道是否有人试图访问属性名称或数组,例如:
const map = {
"dashboard[1]": 'i am string',
"dashboard": [1, 2],
}
因此,如果有人编写了map.dashboard[1]
,那么如果数组的条件高于else条件(else条件=如果不是数组),它将返回“2”而不是“i am string”b/c
我希望它能帮上忙:)确实obj[data.users.admins.dashboard[3]]
(不带引号)不做你想做的事吗?更新问题谢谢如果你要使用eval,那么你不需要代理obj={a:{b:{c:1}};路径='a.b.c';eval(`obj.${path}`)代码>是的,您是正确的,但是每次从对象获取值时都必须使用eval。您还可以将eval更改为常规代码——更新了答案@MuhammadUmer
const obj = new Proxy({
data: {
users: {
admins: {
dashboard: [10, 21, 31, 41, {
hi: 'I am hi'
}],
}
}
},
}, {
get: function (map, key, receiver) {
try {
let splitedKey = key.split(".");
let current = map;
while (splitedKey.length > 0) {
let newValue = splitedKey.shift();
let openingBracketIndex = newValue.lastIndexOf("[");
let arrIndex = Number(newValue.slice(openingBracketIndex + 1, newValue.length - 1));
let isArr = !isNaN(arrIndex)
if (openingBracketIndex > -1 && newValue[newValue.length - 1] === "]" && isArr) {
let arrName = newValue.slice(0, openingBracketIndex);
current = current[arrName][arrIndex];
} else {
current = current[newValue];
}
}
return current;
} catch (error) {
return undefined;
};
},
});
console.log(obj['data.users.admins.dashboard[3]'] == 41);
console.log(obj['data.users.admins.dashboard[0]'] == 10);
console.log(obj["data.users.admins.dashboard[4].hi"] === "I am hi");
console.log(obj['erter.sdfdsfds.admins.sdfsdf[3]'] === undefined)
const map = {
"dashboard[1]": 'i am string',
"dashboard": [1, 2],
}