我有一个这样的数据结构:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
我想使用这些变量访问数据:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name应该用someObject.part1.name的值填充,即“Part 1”。part2quantity也是一样,它的容量是60。
有没有办法实现这与纯javascript或JQuery?
而不是尝试模拟JS语法,你将不得不花费大量的计算解析,或者只是错误/忘记一些事情,比如一堆这些答案(带.s的键,有人吗?),只是使用一个键数组。
var part1name = Object.get(someObject, ['part1', 'name']);
var part2quantity = Object.get(someObject, ['part2', 'qty']);
var part3name1 = Object.get(someObject, ['part3', 0, 'name']);
如果您需要使用单个字符串,只需JSONify它。
此方法的另一个改进是您可以删除/设置根级对象。
function resolve(obj, path) {
let root = obj = [obj];
path = [0, ...path];
while (path.length > 1)
obj = obj[path.shift()];
return [obj, path[0], root];
}
Object.get = (obj, path) => {
let [parent, key] = resolve(obj, path);
return parent[key];
};
Object.del = (obj, path) => {
let [parent, key, root] = resolve(obj, path);
delete parent[key];
return root[0];
};
Object.set = (obj, path, value) => {
let [parent, key, root] = resolve(obj, path);
parent[key] = value;
return root[0];
};
其他功能演示:
对于.set(/.del()的bob =是不必要的,除非你的路径可能是空的(操作根对象)。
我证明我不克隆的对象使用史蒂夫保持原始的引用和检查bob == steve //true后,第一个.set(
这是我使用的解决方案:
function resolve(path, obj=self, separator='.') {
var properties = Array.isArray(path) ? path : path.split(separator)
return properties.reduce((prev, curr) => prev?.[curr], obj)
}
使用示例:
// accessing property path on global scope
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// accessing array indexes
// (someObject has been defined in the question)
resolve("part3.0.size", someObject) // returns '10'
// accessing non-existent properties
// returns undefined when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
// accessing properties with unusual keys by changing the separator
var obj = { object: { 'a.property.name.with.periods': 42 } }
resolve('object->a.property.name.with.periods', obj, '->') // returns 42
// accessing properties with unusual keys by passing a property name array
resolve(['object', 'a.property.name.with.periods'], obj) // returns 42
限制:
不能将方括号([])用于数组下标-尽管在分隔符令牌之间指定数组下标(例如,.)可以正常工作,如上所示。
而不是尝试模拟JS语法,你将不得不花费大量的计算解析,或者只是错误/忘记一些事情,比如一堆这些答案(带.s的键,有人吗?),只是使用一个键数组。
var part1name = Object.get(someObject, ['part1', 'name']);
var part2quantity = Object.get(someObject, ['part2', 'qty']);
var part3name1 = Object.get(someObject, ['part3', 0, 'name']);
如果您需要使用单个字符串,只需JSONify它。
此方法的另一个改进是您可以删除/设置根级对象。
function resolve(obj, path) {
let root = obj = [obj];
path = [0, ...path];
while (path.length > 1)
obj = obj[path.shift()];
return [obj, path[0], root];
}
Object.get = (obj, path) => {
let [parent, key] = resolve(obj, path);
return parent[key];
};
Object.del = (obj, path) => {
let [parent, key, root] = resolve(obj, path);
delete parent[key];
return root[0];
};
Object.set = (obj, path, value) => {
let [parent, key, root] = resolve(obj, path);
parent[key] = value;
return root[0];
};
其他功能演示:
对于.set(/.del()的bob =是不必要的,除非你的路径可能是空的(操作根对象)。
我证明我不克隆的对象使用史蒂夫保持原始的引用和检查bob == steve //true后,第一个.set(