获得嵌套对象属性的更好方法

时间:2013-09-05 10:46:39

标签: javascript jquery underscore.js

通常在远程API调用的响应中,我会收到嵌套对象:

var response = {
    data : {
        users : [
            {
                name : 'Mr. White'
            }
        ]
    }
}

我想检查第一个用户的名字是'先生'白色',并且自然希望写出类似的东西。

var existed = response.data.users[0].name === 'Mr. White'

但是我不能确定是否所有对象都存在,所以为了避免异常,我最终写了:

var existed = response && response.data && response.data.users && response.data.users[0].name === 'Mr. White'

有更好的方法吗?想到的另一个丑陋的选择是:

var existed = false;
try {
    var existed = response.data.users[0].name === 'Mr. White';
} catch(e) { }

除了v​​anilla javascript之外,我通常还有underscore.js和jquery。

修改

哎呀,注意到我问了一个javascript test for existence of nested object key的傻瓜。

基于这些答案的有趣选择是:

var existed = (((response || {}).data || {}).users || [{}])[0].name === 'Mr. White';

4 个答案:

答案 0 :(得分:1)

我会使用try catch方法,但将其包装在函数中以隐藏丑陋。

答案 1 :(得分:1)

你可以在这样的函数中隐藏这个顽皮的try / catch块:

function resolve(root, path){
    try {
        return (new Function(
            'root', 'return root.' + path + ';'
        ))(root);
    } catch (e) {}
}

var tree = { level1: [{ key: 'value' }] };
resolve(tree, 'level1[0].key'); // "value"
resolve(tree, 'level1[1].key'); // undefined

更多相关信息:https://stackoverflow.com/a/18381564/1636522

答案 2 :(得分:1)

而不是try/catch,这应该通过检查对象中的每个级别是否已定义来完成。

去寻找

if(typeof(response)!="undefined" 
  && typeof(response.data)!="undefined"
  && typeof(response.data.users)!="undefined"
  && typeof(response.data.users[0])!="undefined"
  && typeof(response.data.users[0].name)!="undefined"
) {

    //executes only if response.data.users[0].name is existing

}

答案 3 :(得分:1)

这是我在我的一个项目http://jsfiddle.net/JBBAJ/

中使用的函数
var object = {
    data: {
        users: [
            {
                firstName: "White"
            },
            {
                firstName: "Black"
            }
        ]
    }
}
var read = function(path, obj) {
    var path = path.split(".");
    var item = path.shift();
    if(item.indexOf("]") == item.length-1) {
        // array
        item = item.split("[");
        var arrayName = item.shift();
        var arrayIndex = parseInt(item.shift().replace("]", ""));
        var arr = obj[arrayName || ""];
        if(arr && arr[arrayIndex]) {
            return read(path.join("."), arr[arrayIndex]);
        } else {
            return null;
        }
    } else {
        // object
        if(obj[item]) {
            if(path.length === 0) {
                return obj[item];
            } else {
                return read(path.join("."), obj[item]);
            }
        } else {
            return null;
        }
    }

}
console.log(read("data.users[0].firstName", object)); // White
console.log(read("data.users[1].firstName", object)); // Black
console.log(read("data.test.users[0]", object)); // null

我们的想法是将您的路径作为字符串与您的对象一起传递。这个想法是为了防止抛出异常,并且由于路径错误而只接收null。好处是该函数适用于每个路径,并且您不需要编写long if语句。