测试是否存在嵌套的JavaScript对象键

如果我对某个对象有引用:

var测试={};

可能(但不是立即)具有嵌套对象的对象,例如:

{level1:{level2:{level3:{level3}}};

检查深度嵌套对象中是否存在属性的最佳方法是什么

警报(测试级别1)产生未定义,但发出警报(test.level1.level2.level3)失败

我目前正在做这样的事情:

if(test.level1&test.level1.level2&test.level1.level2.level3){
警报(测试级别1.级别2.级别3);
}

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

如果您不希望出现类型错误,则必须一步一步地执行此操作,因为如果其中一个成员为null未定义,并且您尝试访问一个成员,将引发异常

您可以简单地捕获异常,或者创建一个函数来测试是否存在多个级别,如下所示:

函数checkNested(obj/*,level1,level2,…levelN*/){
var args=Array.prototype.slice.call(参数,1);
对于(变量i=0;i<args.length;i++){
if(!obj | |!obj.hasOwnProperty(args[i])){
返回false;
}
obj=obj[args[i]];
}
返回true;
}
var test={level1:{level2:{level3:'level3'}}};
checkNested(测试'level1','level2','level3');//符合事实的
checkNested(测试'level1','level2','foo');//错误的

ES6更新:

下面是原始函数的一个较短版本,使用ES6特性和递归(它也是正确的尾部调用形式):

函数检查嵌套(obj、级别、…rest){
if(obj==未定义)返回false
if(rest.length==0&obj.hasOwnProperty(level))返回true
返回checkNested(对象[级别],…剩余)
}

但是,如果您希望获取嵌套属性的值,而不仅仅是检查其存在性,那么这里有一个简单的单行函数:

函数getNested(obj,…args){
返回参数减少((对象,级别)=>对象和对象[级别],对象)
}
常量测试={level1:{level2:{level3:'level3'}};
log(getNested(测试'level1','level2','level3');/'三级'
log(getNested(测试'level1','level2','level3','length');//6.
log(getNested(测试'level1','level2','foo');//未定义
log(getNested(测试'a','b');//未定义的

上述函数允许您获取嵌套属性的值,否则将返回undefined

更新2019-10-17:

可选链接建议在ECMAScript委员会流程上达到第3阶段,这将允许您使用新的可选链接操作符,即令牌?。,安全地访问深度嵌套的属性:

const value=obj?.level1?.level2?.level3

如果访问的任何级别为nullundefined则表达式将自行解析为undefined

该方案还允许您安全地处理方法调用:

obj?.level1?.method();

如果objobj.level1obj.level1.methodnullundefined,则上述表达式将生成undefined,否则它将调用该函数

您可以使用可选的链接插件在Babel上开始使用此功能。

自Babel 7.8.0以来,默认情况下支持ES2020

请在Babel REPL上查看此示例

🎉🎉更新:2019年12月🎉🎉

在TC39委员会2019年12月的会议上,可选链接提案最终进入第4阶段。这意味着此功能将成为ECMAScript 2020标准的一部分

发表评论