Ви повинні робити це поетапно, якщо ви не хочете, 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 підтримується за замовчуванням
Перевірте цей приклад на вабельній REPL.
🎉🎉УПОДАТ: грудень 2019 🎉🎉
Необов'язкова пропозиція ланцюга, нарешті, досягла 4 етапу на засіданні комітету TC39 у грудні 2019 року. Це означає, що ця функція буде частиною стандарту ECMAScript 2020 .