te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to check if object structure exists? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to check if object structure exists? - Stack Overflow

programmeradmin4浏览0评论

Lets say I parse a JSON object from a 3rd party source:

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

But if the structure suddenly changes or perhaps the data response was corrupt, how can I check the existence of the in depth parts of the structure?

I can do

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

But maybe black_hair doesn't exist in some cases. If it's missing from the object, then I get a Uncaught TypeError: Cannot read property 'list' of undefined. So the only way I can think of to check if the entire structure is plete is to check if each level is defined:

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

But that is a little bit ridiculous. Is there a simple way to handle this in JavaScript? Is a try, catch the best approach?

Lets say I parse a JSON object from a 3rd party source:

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

But if the structure suddenly changes or perhaps the data response was corrupt, how can I check the existence of the in depth parts of the structure?

I can do

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

But maybe black_hair doesn't exist in some cases. If it's missing from the object, then I get a Uncaught TypeError: Cannot read property 'list' of undefined. So the only way I can think of to check if the entire structure is plete is to check if each level is defined:

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

But that is a little bit ridiculous. Is there a simple way to handle this in JavaScript? Is a try, catch the best approach?

Share Improve this question asked Jul 24, 2014 at 3:05 Jake WilsonJake Wilson 91.2k96 gold badges260 silver badges371 bronze badges 5
  • 4 did you tried this if(myObject && myObject.peson_list && myObject.peson_list.black_hair && myObject.peson_list.black_hair.list){} – Mritunjay Commented Jul 24, 2014 at 3:08
  • 2 Could you use jQuery.extend() to create a base-level object? The values might be empty but at least they wouldn't be undefined. It would depend on how large you're expecting myObject to be – jasonscript Commented Jul 24, 2014 at 3:09
  • 1 Actually you don't expect the structure to be broken. So I'd say this is a model case for when to use a try-catch statement. Otherwise you'd check for way too many things and probably you overlook something. Like what if person_list isn't undefined but null? – Robert Commented Jul 24, 2014 at 4:32
  • 1 The question is flawed in that the given structure of myObject.person_list.black_hair.list is undefined anyway, since black_hair is not a property of person_list. but rather a property of the object which is the first element in the person_list array, so the actual "structure" of this object is myObject.person_list[0].black_hair.list so answers given so far would correctly yield false if testing for the structure of myObject.person_list.black_hair.list – chiliNUT Commented Jul 24, 2014 at 4:39
  • @chiliNUT good point! I've updated my answer. – S. A. Commented Jul 24, 2014 at 5:07
Add a ment  | 

4 Answers 4

Reset to default 4

You could define a function to check the full structure for you:

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
}

The first parameter is the object with structure to be checked, and the second one is an array with the name of the nested properties.

Update:

As pointed out by @chiliNUT, person_list is an array. Anyway, this approach works by adding the index of the item you want to check (i.e. ['person_list', 0, 'black_hair', 'list']).

you can use this function I wrote to check whether the property is set. You just need to pass the path to the property as a string.

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

just a bit better way with meta object which maps the expected format

var meta = {
    name: "person_list",
    type: [],
    ponent: [{
        name: 'black_hair',
        type: {},
        ponent: {
            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.ponent[index], obj[meta.name][index]);
        }
    } else if (Object.prototype.toString.call(meta.type) === '[object Object]') {
        return defined(meta.ponent, obj[meta.name]);
    }
}

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

DEMO

you can do like

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

You can refer this : Optional chaining

发布评论

评论列表(0)

  1. 暂无评论