如果我有对象的引用:

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

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


当前回答

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

其他回答

我编写了一个名为l33teral的库来帮助测试嵌套财产。您可以这样使用:

var myObj = {/*...*/};
var hasNestedProperties = leet(myObj).probe('prop1.prop2.prop3');

我也很喜欢这里的ES5/6解决方案。

怎么样

try {
   alert(test.level1.level2.level3)
} catch(e) {
 ...whatever

}

如果像字符串一样处理名称:“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。

在html模板中使用一行程序并没有真正好的答案,所以我使用ES6代理做了一个。您只需将一个对象或值传递给“遍历”函数,并使用返回值或回退值的函数调用来完成所需的嵌套调用。使用:

const testObject={深度:{嵌套:{对象:{closure:()=>{return“closure”},数量:9,布尔值:真,数组:[1,2,{foo:{bar:true}}]} }}}遍历(testObject).dep()//{嵌套:{…}}遍历(testObject).non.existint()//未定义的遍历(testObject).dep.enested.obj.closure()//关闭遍历(testObject).dep.enested.obj.array[5]('fallback')//后退,后退遍历(testObject).dep.enested.obj.array[2]()//{foo:{…}}遍历(testObject).dep.enested.obj.array[2].foo.bar()//真的遍历(testObject).dept.netnested.obj.array[2].foo.bar[4]('fallback')//后退,后退遍历(testObject).完全.错误[3].调用().WILL_THROW()//未捕获的TypeError:无法读取未定义的属性“WILL_TROW”

函数本身:

常量遍历=(输入)=>{//唯一空对象const unset=新对象();//我们需要包装器来确保我们可以访问同一个唯一的空对象常量闭包=(输入)=>{//将每个输入包装到此const handler=new Function();handler.input=输入;//返回包装器代理返回新代理(handler{//保持横向移动获取:(target,name)=>{//如果未定义,则作为初始输入提供if(!target.input){返回关闭(未设置);}//否则if(target.input[name]!==未定义){//输入具有该属性返回闭包(target.input[name]);}其他{返回关闭(未设置);}},//带回退的结果apply:(目标,上下文,参数)=>{return handler.input==未设置?args[0]:handler.input;}})}返回闭合(输入);}

最好、最简单的答案是:

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

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