如何检查对象结构是否存在?

问题描述 投票:0回答:4

假设我从第 3 方源解析 JSON 对象:

var myObject = {
  person_list: [
    { black_hair: {
      list: [
        'bob',
        'john',
        'allen'
      ]}
    }
  ]
};

但是如果结构突然发生变化或者数据响应可能损坏,我如何检查结构的深层部分是否存在?

我可以做

if ( myObject.person_list.black_hair.list !== undefined ) {
  // do stuff
}

但也许在某些情况下

black_hair
不存在。如果物体缺少它,那么我会得到一个
Uncaught TypeError: Cannot read property 'list' of undefined
。所以我能想到的检查整个结构是否完整的唯一方法就是检查每个级别是否已定义:

if ( myObject.person_list !== undefined ) {
  if ( myObject.person_list.black_hair !== undefined ) {
    if ( myObject.person_list.black_hair.list !== undefined ) {
      // do stuff
    }
  }
}

但这有点荒谬。 JavaScript 有没有一种简单的方法来处理这个问题?尝试一下,抓住最好的方法吗?

javascript json javascript-objects
4个回答
4
投票

您可以定义一个函数来检查完整的结构:

function defined_structure(obj, attrs) {

    var tmp = obj;

    for(i=0; i<attrs.length; ++i) {
        if(tmp[attrs[i]] == undefined)
            return false;
        tmp = tmp[attrs[i]];
    }

    return true;
}

//...

if(defined_structure(myObject, ['person_list', 0, 'black_hair', 'list']) {
    // Do stuff
}

第一个参数是要检查的结构的对象,第二个参数是一个包含嵌套属性名称的数组。

更新:

正如@chiliNUT 所指出的,

person_list
是一个数组。无论如何,这种方法的工作原理是添加您要检查的项目的索引(即
['person_list', 0, 'black_hair', 'list']
)。


1
投票

您可以使用我编写的这个函数来检查属性是否已设置。您只需将属性的路径作为字符串传递即可。

// Check if nested object properties exist on unlimited levels
// param: str 'obj.property.property'
function isset (property)
{
    // split path to object property
    var properties = property.split('.');
    var obj = this;

    //loop through each portion of the path checking if it exists
    for (var i = 0; i < properties.length; i++)
    {
        var current_property = properties[i];
        var next_property = i < properties.length - 1 ? true : false;

        // IF current property exists then we need to check the next level
        if (obj[current_property] !== null && typeof obj[current_property] === 'object' && next_property)
        {
            obj = obj[current_property];
            continue;
        }
        return obj.hasOwnProperty(current_property);
    }
}

if ( isset('myObject.person_list.black_hair.list')) {
    // do stuff
}

1
投票

使用 meta 对象映射预期格式是一个更好的方法

var meta = {
    name: "person_list",
    type: [],
    component: [{
        name: 'black_hair',
        type: {},
        component: {
            name: 'list',
            type: []
        }
    }]
};

var myObject = {
    person_list: [{
        asdfa: {
            list: [
                'bob',
                'john',
                'allen']
        }
    }]
};

function defined(meta, obj) {
    if (meta.name == 'list' && obj[meta.name] && obj[meta.name].length) {
        return true;
    }
    if (!obj[meta.name]) {
        return false;
    };
    if (Object.prototype.toString.call(meta.type) === '[object Array]' && !obj[meta.name].length) {
        return false;
    } else if (Object.prototype.toString.call(meta.type) === '[object Array]' && obj[meta.name].length) {
        for (index in obj[meta.name]) {
            return defined(meta.component[index], obj[meta.name][index]);
        }
    } else if (Object.prototype.toString.call(meta.type) === '[object Object]') {
        return defined(meta.component, obj[meta.name]);
    }
}

console.log(defined(meta, myObject));

演示


0
投票

你可以这样做

if ( myObject?.person_list?.black_hair?.list !== undefined ) {
  // do stuff
}

您可以参考this:可选链接

© www.soinside.com 2019 - 2024. All rights reserved.