2

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

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

我想检查第一个用户的名字是否是“先生”。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) { }

除了 vanilla javascript,我通常还有 underscore.js 和 jquery 可用。

编辑:

哎呀,注意到我问了一个javascript test 是否存在嵌套对象 key

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

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

4 回答 4

1

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

于 2013-09-05T10:51:20.080 回答
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

于 2013-09-05T10:52:17.960 回答
1

而不是 a 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

}
于 2013-09-05T10:54:08.860 回答
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 。好消息是该函数适用于每条路径,您不需要编写长 if 语句。

于 2013-09-05T11:06:16.157 回答