JavaScript:使用变量访问对象的多级属性

8

如果我使用变量作为键,如何访问多级属性?

以下方法不起作用:

var obj = {
    first: {thirst: "yo"},
    second: {beckon: "dud"}
}
var key = "first.thirst";
var result = obj[key];

2
除非您使用 eval 或编写自定义函数遍历树,否则无法实现。 - Rob W
将此放入答案中,并附上一个示例,我可以接受它作为答案 :) - EricC
3个回答

20

在 JavaScript 中,如果您将字符串用作属性名称,那么没有任何禁止使用的字符,包括句点。因此,您可以轻松地拥有类似于以下对象属性:

var o = {
    'first.second.third': 'value';
}

鉴于此,显然无法实现您的解决方案。

但是,只要您在属性命名中不使用句号,就可以创建一个执行此操作的函数:

function resolve(obj, path){
    path = path.split('.');
    var current = obj;
    while(path.length) {
        if(typeof current !== 'object') return undefined;
        current = current[path.shift()];
    }
    return current;
}

那么你可以这样调用:

var key = "first.thirst";
var result = resolve(obj, key);

6
您可以像@RobW所说的那样遍历树:

var traverse = function (obj, keys) {
    return keys.split('.').reduce(function (cur, key) {
        return cur[key];
    }, obj);
};

var obj = {
    first: { thirst: 'yo' },
    second: { beckon: 'dud' }
};
var keys = 'first.thirst';
console.log(traverse(obj, keys));


哦,没有简单的一行代码解决 :( 但至少这个方法可行!感谢大家! - EricC
两个评论。首先,“traverse”是一个糟糕的名称:这个函数遍历对象树的事实只是一种实现细节。它实际上正在解析对象中的路径;它只是碰巧使用了一个失败的深度优先遍历。其次,如果路径无效,此函数将抛出异常。也许这正是你想要的,但在JavaScript中通常不是这样。否则,干得好! - Ethan Brown

1
function getMultiLevelProp(obj, key){
if(typeof obj == "object"){
    var keyQueue = key.split(".").reverse();

    var tempVal = obj, currentKey;
    while((currentKey = keyQueue.pop()) != undefined)
            tempVal = tempVal[currentKey];

    return tempVal;
}

return false;}

这可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接