Вы должны делать это шаг за шагом, если не хотите, 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
если obj
, obj.level1
или obj.level1.method
являются null
илиundefined
, иначе это вызовет функцию.
Вы можете начать играть с этой функцией с Babel, используя дополнительный плагин цепочки .
Начиная с Babel 7.8.0 , ES2020 поддерживается по умолчанию
Проверьте этот пример на Babel REPL.
«ОБНОВЛЕНИЕ: декабрь 2019»
Факультативное предложение о цепочке, наконец, достигло стадии 4 на заседании комитета TC39 в декабре 2019 года. Это означает, что эта функция будет частью стандарта ECMAScript 2020 .