如果我有对象的引用:

var test = {};

可能(但不是立即)具有嵌套对象,例如:

{level1: {level2: {level3: "level3"}}};

检查深度嵌套对象中是否存在属性的最佳方法是什么?

警报(测试级别1);生成未定义,但警告(test.level1.level2.level3);失败。

我目前正在做这样的事情:

if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
    alert(test.level1.level2.level3);
}

但我想知道是否有更好的方法。


当前回答

怎么样

try {
   alert(test.level1.level2.level3)
} catch(e) {
 ...whatever

}

其他回答

/**
 * @method getValue
 * @description simplifies checking for existance and getting a deeply nested value within a ceratin context
 * @argument {string} s       string representation of the full path to the requested property 
 * @argument {object} context optional - the context to check defaults to window
 * @returns the value if valid and set, returns undefined if invalid / not available etc.
 */
var getValue = function( s, context ){
    var fn = function(){
        try{
            return eval(s);
        }catch(e){
            return undefined;
        }
    }
    return fn.call(context||window,s);
}

和用法:

if( getValue('a[0].b[0].b[0].d') == 2 ) // true

一个简短的ES5版本@CMS的优秀答案:

// Check the obj has the keys in the order mentioned. Used for checking JSON results.  
var checkObjHasKeys = function(obj, keys) {
  var success = true;
  keys.forEach( function(key) {
    if ( ! obj.hasOwnProperty(key)) {
      success = false;
    }
    obj = obj[key];
  })
  return success;
}

通过类似测试:

var test = { level1:{level2:{level3:'result'}}};
utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false

这适用于所有对象和阵列:)

ex:

if( obj._has( "something.['deep']['under'][1][0].item" ) ) {
    //do something
}

这是我对Brian答案的改进版

我使用_has作为属性名称,因为它可能与现有的has属性(例如:maps)冲突

Object.defineProperty( Object.prototype, "_has", { value: function( needle ) {
var obj = this;
var needles = needle.split( "." );
var needles_full=[];
var needles_square;
for( var i = 0; i<needles.length; i++ ) {
    needles_square = needles[i].split( "[" );
    if(needles_square.length>1){
        for( var j = 0; j<needles_square.length; j++ ) {
            if(needles_square[j].length){
                needles_full.push(needles_square[j]);
            }
        }
    }else{
        needles_full.push(needles[i]);
    }
}
for( var i = 0; i<needles_full.length; i++ ) {
    var res = needles_full[i].match(/^((\d+)|"(.+)"|'(.+)')\]$/);
    if (res != null) {
        for (var j = 0; j < res.length; j++) {
            if (res[j] != undefined) {
                needles_full[i] = res[j];
            }
        }
    }

    if( typeof obj[needles_full[i]]=='undefined') {
        return false;
    }
    obj = obj[needles_full[i]];
}
return true;
}});

这是小提琴

另一个ES5解决方案:

function hasProperties(object, properties) {
    return !properties.some(function(property){
        if (!object.hasOwnProperty(property)) {
            return true;
        }
        object = object[property];
        return false;
    });
}

创建全局函数并在整个项目中使用

试试这个

函数isExist(arg){尝试{返回参数();}捕获(e){return false;}}让obj={a:5,b:{c:5}};console.log(isExist(()=>obj.b.c))console.log(isExist(()=>obj.b.foo))console.log(isExist(()=>obj.test.foo))

if条件

if(isExist(()=>obj.test.foo)){
   ....
}