如果我有对象的引用:

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

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


当前回答

您还可以将tc39可选链接建议与babel 7-tc39建议可选链接一起使用

代码如下所示:

  const test = test?.level1?.level2?.level3;
  if (test) alert(test);

其他回答

从这个答案开始,阐述了以下选项。两者的树相同:

var o = { a: { b: { c: 1 } } };

未定义时停止搜索

var u = undefined;
o.a ? o.a.b ? o.a.b.c : u : u // 1
o.x ? o.x.y ? o.x.y.z : u : u // undefined
(o = o.a) ? (o = o.b) ? o.c : u : u // 1

逐一确保每个级别

var $ = function (empty) {
    return function (node) {
        return node || empty;
    };
}({});

$($(o.a).b).c // 1
$($(o.x).y).z // undefined

我尝试了递归方法:

function objHasKeys(obj, keys) {
  var next = keys.shift();
  return obj[next] && (! keys.length || objHasKeys(obj[next], keys));
}

这个keys.length||退出递归,这样它就不会在没有键可供测试的情况下运行函数。测验:

obj = {
  path: {
    to: {
      the: {
        goodKey: "hello"
      }
    }
  }
}

console.log(objHasKeys(obj, ['path', 'to', 'the', 'goodKey'])); // true
console.log(objHasKeys(obj, ['path', 'to', 'the', 'badKey']));  // undefined

我正在使用它打印一组具有未知键/值的对象的友好html视图,例如:

var biosName = objHasKeys(myObj, 'MachineInfo:BiosInfo:Name'.split(':'))
             ? myObj.MachineInfo.BiosInfo.Name
             : 'unknown';
getValue (o, key1, key2, key3, key4, key5) {
    try {
      return o[key1][key2][key3][key4][key5]
    } catch (e) {
      return null
    }
}

我自动化了流程

if(isset(object,["prop1","prop2"])){
// YES!

}

function isset(object, props){
    var dump;
    try {
        for(var x in props){
            if(x == 0) {
                dump = object[props[x]];
                return;
            }
            dump = dump[props[x]];
        }
    } catch(e) {
        return false;
    }

    return true;
}

您可以使用“.”分隔对象和路径

函数checkPathExist(obj,路径){var pathArray=路径.split(“.”)for(pathArray的var i){if(反射get(obj,i)){obj=obj[i];}其他{return false;}}返回true;}var测试={level1:{level2:{level3:‘level3‘}}}};console.log('level.level.level3=>',checkPathExist(测试,'level.level 2.level3'));//真的console.log('level.level.foo=>',checkPathExist(测试,'level.level 2.foo'));//假的