如果我有对象的引用:

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

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


当前回答

另一个ES5解决方案:

function hasProperties(object, properties) {
    return !properties.some(function(property){
        if (!object.hasOwnProperty(property)) {
            return true;
        }
        object = object[property];
        return false;
    });
}

其他回答

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

代码如下所示:

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

我自动化了流程

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

最好、最简单的答案是:

var isDefinedPath = function (path) {

    var items = path.split ('.');

    if (!items || items.length < 1 || !(items[0] in window)) { return false; }

    var buffer = [items[0]];
    for (var i = 1, e = items.length; i < e; i ++) {
        buffer.push (items[i]);
        if (eval ('typeof(' + buffer.join ('.') + ') == "undefined"')) {
            return false;
        }
    }

    return true;

}

测试:isDefinedPath('level.level.level3');

第一级不能是数组,其他级别可以

/**
 * @method getValue
 * @description simplifies checking for existance and getting a deeply nested value within a ceratin context
 * @argument {string} s       string representation of the full path to the requested property 
 * @argument {object} context optional - the context to check defaults to window
 * @returns the value if valid and set, returns undefined if invalid / not available etc.
 */
var getValue = function( s, context ){
    var fn = function(){
        try{
            return eval(s);
        }catch(e){
            return undefined;
        }
    }
    return fn.call(context||window,s);
}

和用法:

if( getValue('a[0].b[0].b[0].d') == 2 ) // true

另一个ES5解决方案:

function hasProperties(object, properties) {
    return !properties.some(function(property){
        if (!object.hasOwnProperty(property)) {
            return true;
        }
        object = object[property];
        return false;
    });
}