繁体   English   中英

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

[英]How to check if object structure exists?

让我们说我从第三方源解析一个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中处理这个问题吗? 是尝试,抓住最好的方法?

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

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'] )。

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

// 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
}

使用映射预期格式的对象的方法稍微好一些

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));

DEMO

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM