如果我对某个对象有引用:
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
如果访问的任何级别为null或undefined则表达式将自行解析为undefined
该方案还允许您安全地处理方法调用:
obj?.level1?.method();
如果obj、obj.level1或obj.level1.method为null或undefined,则上述表达式将生成undefined,否则它将调用该函数
您可以使用可选的链接插件在Babel上开始使用此功能。
自Babel 7.8.0以来,默认情况下支持ES2020
请在Babel REPL上查看此示例
🎉🎉更新:2019年12月🎉🎉
在TC39委员会2019年12月的会议上,可选链接提案最终进入第4阶段。这意味着此功能将成为ECMAScript 2020标准的一部分