考虑波纹管对象和存储在对象中的值的路径:
var obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 }
var path = ["b", "a", "x"];
在对象路径中获取内容的最佳方式(最佳性能)是什么?
使用eval()
path = ["obj"].concat(path);
var value = eval(path.join("."));
循环
var _obj = obj;
for(key in path) {
_obj = _obj[path[key]];
}
var value = _obj;
还有其他更好的方法来存储和查询对象复合体吗?
答案 0 :(得分:3)
您可以使用路径并使用Array#reduce
作为对象。
function getValue(object, path) {
return path.reduce(function (o, k) {
return (o || {})[k];
}, object);
}
var obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 }
path = ["b", "a", "x"];
console.log(getValue(obj, path));
答案 1 :(得分:2)
递归版:
function getPath(obj, [head, ...tail]) {
return !obj ? null : !head ? obj : getPath(obj[head], tail);
}
var obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 };
var path = ["b", "a", "x"];
console.log(getPath(obj, path));
答案 2 :(得分:1)
eval
很慢。循环很快,所以我建议您使用...
var obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 }
var path = ["b", "a", "x"];
function getDeep(object, path) {
for (var i = 0; i < path.length; i++) {
if (object == null) return
object = object[path[i]]
}
return object
}
console.log(getDeep(obj, path)) //=> 2
答案 3 :(得分:1)
如果您知道您正在使用的那个对象具有该属性,那么您应该使用它:
const createAccesor = path => {
let func = 'return obj'
for (let i = 0; i < path.length; i++){
func += `['${path[i]}']`
}
return Function('obj', func)
}
const obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 }
const acces = createAccesor(['b', 'a', 'x'])
console.log(acces(obj))
这是 speed test 。 此解决方案的问题在于,当对象不包含您在路径中指定的prop时,它将抛出。
或使用效率较低的访问者:
const createAccesor = path => {
let func = 'let temp=obj;'
for (let i = 0; i < path.length; i++){
func += `if(temp=temp['${path[i]}'])`
}
func += ';return temp'
return Function('obj', func)
}
const obj = { a: 1, b: { a: { x: 2 }, b: 3 }, c: 4 }
const acces = createAccesor(['b', 'n', 'x', 'n'])
const acces2 = createAccesor(['b', 'a', 'x'])
console.log(acces(obj))
console.log(acces2(obj))
请注意,只有当您有多个“查询”对象或多次使用此对象时才会加速,否则您将无法获得任何速度。
eval
的问题在于,如果它在内部函数中出现,则无法通过js引擎进行优化。
您也可以为自己创建“语法”,例如,而不是p array
,您可以像'b->a->x'
或'b.a.x'
那样传递'acces string',然后只需调用split in function with / - &gt; / g或'。'它不会影响你的访问速度,它看起来更好看:D而且你不必写',所有的时间