如果我有对象的引用:

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

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


当前回答

我已经使用这个函数来访问深度嵌套对象的财产,它对我来说很有效。。。

这是函数

/**
 * get property of object
 * @param obj object
 * @param path e.g user.name
 */
getProperty(obj, path, defaultValue = '-') {
  const value = path.split('.').reduce((o, p) => o && o[p], obj);

  return value ? value : defaultValue;
}

这是我访问深度嵌套对象属性的方式

{{ getProperty(object, 'passengerDetails.data.driverInfo.currentVehicle.vehicleType') }}

其他回答

一个简单的方法是:

try {
    alert(test.level1.level2.level3);
} catch(e) {
    alert("undefined");    // this is optional to put any output here
}

try/catch捕捉未定义任何更高级别对象(如test、test.level1、test.level1.level2)时的情况。

简单使用https://www.npmjs.com/package/js-aid用于检查嵌套对象的包。

另一个选项(接近这个答案):

function resolve(root, path){
    try {
        return (new Function(
            'root', 'return root.' + path + ';'
        ))(root);
    } catch (e) {}
}

var tree = { level1: [{ key: 'value' }] };
resolve(tree, 'level1[0].key'); // "value"
resolve(tree, 'level1[1].key'); // undefined

更多信息:https://stackoverflow.com/a/18381564/1636522

现在,我们还可以使用reduce循环嵌套键:

//@params o<对象>//@params路径<string>应为“obj.prop1.prop2.prop3”//返回:obj[path]值或“false”(如果prop不存在)const objPropIfExists=o=>路径=>{常量级别=路径.split('.');常量res=(levels.length>0)? level.reduce((a,c)=>a[c]||0,o):o[路径];return(!!res)?res:假}常量对象={name:'名称',sys:{country:“AU”},main:{temp:“34”,temp_min:“13”},能见度:“35%”}const exists=objPropIfExists(obj)('main.temp')const doesntExist=objPropIfExists(obj)('main.temp.foo.baz')console.log(存在,不存在)

下面是我的看法-这些解决方案中的大多数都忽略了嵌套数组的情况,如:

    obj = {
        "l1":"something",
        "l2":[{k:0},{k:1}],
        "l3":{
            "subL":"hello"
        }
    }

我可能想检查obj.l2[0].k

使用下面的函数,您可以执行深度测试('l2[0].k',obj)

如果对象存在,函数将返回true,否则返回false

函数deeptest(keyPath,testObj){变量obj;keyPath=keyPath.split('.')var cKey=keyPath.shift();函数get(pObj,pKey){var bracketStart,bracketEnd,o;bracketStart=pKey.indexOf(“[”);if(bracketStart>-1){//检查嵌套数组bracketEnd=pKey.indexOf(“]”);var arrIndex=pKey.substr(bracketStart+1,bracketEnd-bracketStart-1);pKey=pKey.substr(0,括号开始);var n=pObj[pKey];o=n?n[arrIndex]:未定义;}其他{o=pObj[pKey];}返回o;}obj=获取(testObj,cKey);while(obj&&keyPath.length){obj=get(obj,keyPath.shift());}返回typeof(obj)!=='未定义';}变量obj={“l1”:“级别1”,“arr1”:[{“k”:0},{“k”:1},{“k”:2}],“子”:{“a”:“字母a”,“b”:“字母b”}};console.log(“l1:”+深度测试(“l1”,obj));console.log(“arr1[0]:”+深度测试(“arr1[0]”,obj));console.log(“arr1[1].k:”+深度测试(“arr1].k”,obj));console.log(“arr1[1].j:”+深度测试(“arr1].j”,obj));console.log(“arr1[3]:”+深度测试(“arr1[3]”,obj));console.log(“arr2:”+深度测试(“arr2”,obj));