Значением свойства объекта может быть всё, что угодно, включая другой объект или массив:
const user = { name: 'Vasya', married: true, age: 25 };
// Добавим свойство friends со списком друзей
user.friends = ['Kolya', 'Petya'];
// Добавим свойство children со списком детей,
// каждый ребёнок представлен отдельным объектом
user.children = [
{ name: 'Mila', age: 1 },
{ name: 'Petr', age: 10 },
];
// Добавим вложенный объект
user.company = { name: 'Hexlet' };
console.log(user); // =>
// {
// name: 'Vasya',
// married: true,
// age: 25,
// friends: [ 'Kolya', 'Petya' ],
// children: [ { name: 'Mila', age: 1 }, { name: 'Petr', age: 10 }],
// company: { name: 'Hexlet' }
// }
Все то же самое можно определить сразу при создании объекта:
const user = {
name: 'Vasya',
married: true,
age: 25,
friends: ['Kolya', 'Petya'],
children: [
{ name: 'Mila', age: 1 },
{ name: 'Petr', age: 10 },
],
company: {
name: 'Hexlet'
},
};
В этом случае обращение к вложенным элементам происходит по цепочке:
user.friends[1]; // 'Petya'
user.children[0].name; // 'Mila'
user.company.name; // 'Hexlet'
// Или через квадратные скобки
user['children'][0]['name']; // 'Mila'
Печать на экран
В console.log()
встроено одно ограничение. Если в объекте есть другие объекты на глубине больше второго уровня вложенности, то при выводе такого объекта на экран вместо объектов отобразится строка [Object]
, а вместо массива — [Array]
.
const obj = { a: { b: { c: { key: 'value' }, e: [1, 2] } } };
console.log(obj);
// { a: { b: { c: [Object], e: [Array] } } }
Для вывода таких объектов можно воспользоваться функцией преобразования в JSON:
console.log(JSON.stringify(obj));
// {"a":{"b":{"c":{"key":"value"},"e":[1,2]}}}
// Или форматированный вывод
console.log(JSON.stringify(obj, null, ' '));
// {
// "a": {
// "b": {
// "c": {
// "key": "value"
// },
// "e": [
// 1,
// 2
// ]
// }
// }
// }
Проверки в глубину
При работе с вложенными объектами резко усложняется задача проверки существования ключей. Приходится строить цепочку из условий до нужного свойства. Представьте, что нам нужно добраться до 4 уровня вложенности и мы не уверены в том, что существуют все промежуточные объекты:
// Добираемся до obj.one.two.three
if (Object.hasOwn(obj, 'one')) {
if (Object.hasOwn(obj.one, 'two')) {
if (Object.hasOwn(obj.one.two, 'three')) {
// ...
}
}
}
Так будет выглядеть решение в лоб. Однако, есть более удобный способ, речь о котором ниже.
Оператор опциональной последовательности
Если задача состоит в том, чтобы извлечь данные, а не просто проверить их существование, то можно пойти другим путем. В Javascript встроен оператор опциональной последовательности (optional chaining), который позволяет извлекать вложенные данные без проверок:
const obj = {};
obj?.one?.two?.three // undefined
Этот оператор никогда не приводит к ошибке. Он работает на любых типах данных и всегда возвращает либо undefined
, либо значение указанного свойства, если оно существует.
Оператор не меняет общий подход работы с ключами в объектах. Этот же пример с динамическим ключом:
const obj = {};
const key = 'one';
obj?.[key]?.two?.three // undefined
Оператор нулевого слияния
С помощью оператора нулевого слияния, можно не только получить значение цепочки любой вложенности, но и определить значение по умолчанию для него.
const obj = {};
obj?.one?.two?.three ?? 'defaultValue' // 'defaultValue'
Значение по умолчанию возвращается только в том случае, когда слева undefined
или null
. В этом смысле данный оператор совсем не похож на логическое сравнение ||
:
const value = false;
value ?? 'default'; // false
value || 'default'; // 'default'
get (lodash)
Пример выше перегружен символами и выглядит достаточно сложно. Как альтернативу можно использовать функцию get()
библиотеки Lodash.
import _ from 'lodash';
const obj = {};
const value = _.get(obj, 'one.two.three', 'defaultValue'); // 'defaultValue'
get()
особенно удобен в случае динамических ключей. В таком случае вторым аргументом можно передать массив ключей:
_.get(obj, ['one', 'two', 'three'], 'defaultValue'); // 'defaultValue'
Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.