如果您不想要 a,则必须逐步进行,TypeError
因为如果其中一个成员是null
或undefined
,并且您尝试访问某个成员,则会引发异常。
您可以简单地catch
排除异常,也可以创建一个函数来测试多个级别的存在,如下所示:
function checkNested(obj /*, level1, level2, ... levelN*/) {
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < args.length; i++) {
if (!obj || !obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}
var test = {level1:{level2:{level3:'level3'}} };
checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false
ES6 更新:
这是原始函数的较短版本,使用 ES6 特性和递归(它也是正确的尾调用形式):
function checkNested(obj, level, ...rest) {
if (obj === undefined) return false
if (rest.length == 0 && obj.hasOwnProperty(level)) return true
return checkNested(obj[level], ...rest)
}
但是,如果您想获取嵌套属性的值而不只是检查其是否存在,这里有一个简单的单行函数:
function getNested(obj, ...args) {
return args.reduce((obj, level) => obj && obj[level], obj)
}
const test = { level1:{ level2:{ level3:'level3'} } };
console.log(getNested(test, 'level1', 'level2', 'level3')); // 'level3'
console.log(getNested(test, 'level1', 'level2', 'level3', 'length')); // 6
console.log(getNested(test, 'level1', 'level2', 'foo')); // undefined
console.log(getNested(test, 'a', 'b')); // undefined
上面的函数可以让你获取嵌套属性的值,否则会返回undefined
.
更新 2019-10-17:
在可选的链接建议对达到第3阶段ECMAScript委员会的过程,这将让你安全地访问深度嵌套的性质,通过使用令牌?.
,新的可选链接操作:
const value = obj?.level1?.level2?.level3
如果访问的任何级别是null
或undefined
表达式将undefined
自行解析。
该提案还允许您安全地处理方法调用:
obj?.level1?.method();
上面的表达式会产生undefined
if obj
, obj.level1
, or obj.level1.method
are null
or undefined
,否则会调用函数。
您可以使用可选的链接插件在 Babel 中开始使用此功能。
从Babel 7.8.0 开始,默认支持 ES2020
在 Babel REPL 上查看此示例。
🎉🎉更新:2019 年 12 月 🎉🎉
可选链提案最终在 2019 年 12 月的 TC39 委员会会议上进入第 4 阶段。这意味着此功能将成为ECMAScript 2020标准的一部分。