如果我有对象的引用:

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

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


当前回答

您可以使用递归函数来实现这一点。即使您不知道所有嵌套的对象键名称,也可以使用此方法。

function FetchKeys(obj) {
    let objKeys = [];
    let keyValues = Object.entries(obj);
    for (let i in keyValues) {
        objKeys.push(keyValues[i][0]);
        if (typeof keyValues[i][1] == "object") {
            var keys = FetchKeys(keyValues[i][1])
            objKeys = objKeys.concat(keys);
        }
    }
    return objKeys;
}

let test = { level1: { level2: { level3: "level3" } } };
let keyToCheck = "level2";
let keys = FetchKeys(test); //Will return an array of Keys

if (keys.indexOf(keyToCheck) != -1) {
    //Key Exists logic;
}
else {
    //Key Not Found logic;
}

其他回答

如果像字符串一样处理名称:“t.level1。level2。level3”,则可以在任何深度读取对象属性。

window.t={level1:{level2:{level3: 'level3'}}};

function deeptest(s){
    s= s.split('.')
    var obj= window[s.shift()];
    while(obj && s.length) obj= obj[s.shift()];
    return obj;
}

alert(deeptest('t.level1.level2.level3') || 'Undefined');

如果任何段未定义,则返回undefined。

getValue (o, key1, key2, key3, key4, key5) {
    try {
      return o[key1][key2][key3][key4][key5]
    } catch (e) {
      return null
    }
}

这是我从奥利弗·斯蒂尔那里学到的一个模式:

var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
alert( level3 );

事实上,整篇文章讨论了如何在javascript中实现这一点。他决定使用上面的语法(一旦你习惯了,它就不那么难读了)作为成语。

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

函数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'));//假的

我在寻找属性存在时返回的值,所以我通过上面的CMS修改了答案。下面是我想到的:

函数getNestedProperty(obj,key){//从键字符串获取属性数组var财产=key.split(“.”);//遍历财产,如果对象为空或属性不存在,则返回未定义的对于(var i=0;i<属性.length;i++){if(!obj||!obj.hasOwnProperty(财产[i])){回来}obj=obj[财产[i]];}//找到嵌套属性,因此返回值返回obj;}用法:getNestedProperty(测试,“level.level2.level3”)//“level3”getNestedProperty(测试,“level.level2.foo”)//未定义