如果我有对象的引用:

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

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


当前回答

我想我应该再加一个我今天想到的。我对这个解决方案感到自豪的原因是它避免了许多解决方案中使用的嵌套括号,例如Object Wrap(Oliver Steele):

(在本例中,我使用下划线作为占位符变量,但任何变量名称都有效)

//“测试”对象var测试={level1:{level2:{level3:‘level3‘}}}};设_=测试;如果((_=_level1)&&(_=.level2)&&{设level3=_;//做3级的事情}

//您也可以使用“stacked”if语句。如果你的物体很深,这会有帮助。//(除最后一个大括号外,不带嵌套或大括号)设_=测试;如果(_=_.level1)如果(_=_.level2)如果(_=_.level3){设level3=_;//做3级的事情}//或者可以缩进:如果(_=_.level1)如果(_=_.level2)如果(_=_.level3){设level3=_;//做3级的事情}

其他回答

另一个版本:

function nestedPropertyExists(obj, props) {
    var prop = props.shift();
    return prop === undefined
        ? true
        : obj.hasOwnProperty(prop) ? nestedPropertyExists(obj[prop], props) : false;
}

nestedPropertyExists({a:{b:{c:1}}}, ['a','b','c']); // returns true
nestedPropertyExists({a:{b:{c:1}}}, ['a','b','c','d']); // returns false
getValue (o, key1, key2, key3, key4, key5) {
    try {
      return o[key1][key2][key3][key4][key5]
    } catch (e) {
      return null
    }
}

对该答案进行轻微编辑,以允许在路径中嵌套数组

var has=函数(obj,key){return key.split(“.”).every(函数(x){if(类型obj!=“对象”| | obj===空| |!x在obj中)return false;if(obj.constructor==数组)obj=obj[0];obj=obj[x];返回true;});}

检查链接答案的用法:)

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

/**
 * 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;
}

我想我应该再加一个我今天想到的。我对这个解决方案感到自豪的原因是它避免了许多解决方案中使用的嵌套括号,例如Object Wrap(Oliver Steele):

(在本例中,我使用下划线作为占位符变量,但任何变量名称都有效)

//“测试”对象var测试={level1:{level2:{level3:‘level3‘}}}};设_=测试;如果((_=_level1)&&(_=.level2)&&{设level3=_;//做3级的事情}

//您也可以使用“stacked”if语句。如果你的物体很深,这会有帮助。//(除最后一个大括号外,不带嵌套或大括号)设_=测试;如果(_=_.level1)如果(_=_.level2)如果(_=_.level3){设level3=_;//做3级的事情}//或者可以缩进:如果(_=_.level1)如果(_=_.level2)如果(_=_.level3){设level3=_;//做3级的事情}