如果我有一个对象的引用:
var test = {};
可能(但不是立即)有嵌套对象,例如:
{level1: {level2: {level3: "level3"}}};
检查深层嵌套对象中是否存在属性的最佳方法是什么?
alert(test.level1);
产量undefined
,但是alert(test.level1.level2.level3);
失败。
我目前正在做这样的事情:
if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
alert(test.level1.level2.level3);
}
但我想知道是否有更好的方法。
最佳答案
如果您不想出现 TypeError
,则必须逐步执行此操作,因为如果其中一个成员为 null
或 undefined
,并且您尝试访问成员,将会抛出异常。
您可以简单地捕获
异常,或者创建一个函数来测试多个级别是否存在,如下所示:
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 功能和递归(也是 proper tail call 形式):
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更新:
optional chaining proposal ECMAScript committee process 达到第 3 阶段,这将允许您通过使用标记 ?.
(新的可选链接运算符)安全地访问深度嵌套的属性:
const value = obj?.level1?.level2?.level3
如果访问的任何级别为 null
或 undefined
,则表达式将自行解析为 undefined
。
该提案还允许您安全地处理方法调用:
obj?.level1?.method();
如果 obj
、obj.level1
或 obj.level1.method
,上述表达式将生成 undefined
是 null
或 undefined
,否则将调用该函数。
您可以使用 optional chaining plugin 开始使用 Babel 来使用此功能。 .
自 Babel 7.8.0 ,默认支持ES2020
检查this example在 Babel REPL 上。
🎉🎉更新:2019 年 12 月🎉🎉
最终的可选链提案 reached Stage 4在 TC39 委员会 2019 年 12 月的 session 上。这意味着此功能将成为 ECMAScript 2020 标准的一部分。
关于javascript - 测试嵌套 JavaScript 对象键是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60230982/