如果我有对象的引用:

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

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


当前回答

如果您恰好使用AngularJs,则可以使用$parse服务检查是否存在深度对象属性,如下所示:

if( $parse('model.data.items')(vm) ) {
    vm.model.data.items.push('whatever');
}

为了避免这样的陈述:

if(vm.model && vm.model.data && vm.model.data.items) {
    ....
}

不要忘记将$parse服务注入控制器

有关详细信息:https://glebbahmutov.com/blog/angularjs-parse-hacks/

其他回答

function isIn(string, object){
    var arr = string.split(".");
    var notFound = true;
    var length = arr.length;
    for (var i = 0; i < length; i++){
        var key = arr[i];
        if (!object.hasOwnProperty(key)){
            notFound = false;
            break;
        }
        if ((i + length) <= length){
            object = object[key];
        }
    }
    return notFound;
}
var musicCollection = {
    hasslehoff: {
        greatestHits : true
    }
};
console.log(isIn("hasslehoff.greatestHits", musicCollection));
console.log(isIn("hasslehoff.worseHits", musicCollection));

这里是我的基于字符串的分隔符版本。

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

这个问题由来已久。今天,您可以使用可选链接(?.)

let value = test?.level1?.level2?.level3;

资料来源:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

今天刚刚编写了这个函数,它对嵌套对象中的属性进行了深入搜索,如果找到了,则返回该属性的值。

/**
 * Performs a deep search looking for the existence of a property in a 
 * nested object. Supports namespaced search: Passing a string with
 * a parent sub-object where the property key may exist speeds up
 * search, for instance: Say you have a nested object and you know for 
 * certain the property/literal you're looking for is within a certain
 * sub-object, you can speed the search up by passing "level2Obj.targetProp"
 * @param {object} obj Object to search
 * @param {object} key Key to search for
 * @return {*} Returns the value (if any) located at the key
 */
var getPropByKey = function( obj, key ) {
    var ret = false, ns = key.split("."),
        args = arguments,
        alen = args.length;

    // Search starting with provided namespace
    if ( ns.length > 1 ) {
        obj = (libName).getPropByKey( obj, ns[0] );
        key = ns[1];
    }

    // Look for a property in the object
    if ( key in obj ) {
        return obj[key];
    } else {
        for ( var o in obj ) {
            if ( (libName).isPlainObject( obj[o] ) ) {
                ret = (libName).getPropByKey( obj[o], key );
                if ( ret === 0 || ret === undefined || ret ) {
                    return ret;
                }
            }
        }
    }

    return false;
}

现在,我们还可以使用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(存在,不存在)