The value of an object property can be anything, including another object or an array:
const user = { name: 'John', married: true, age: 25 };
// Adding a property called "friends" containing a list of friends
user.friends = ['Samuel', 'Kristian'];
// Adding a property called "children" with a list of children,
// each child is represented by a separate object
user.children = [
{ name: 'Nency', age: 1 },
{ name: 'Peter', age: 10 },
];
// Add a nested object
user.company = { name: 'Hexlet' };
console.log(user); // =>
// {
// name: 'John',
// married: true,
// age: 25,
// friends: [ 'Samuel', 'Kristian' ],
// company: { name: 'Hexlet' },
// children: [ { name: 'Nency', age: 1 }, { name: 'Peter', age: 10 } ]
// }
All of these can be defined immediately when you create an object:
const user = {
name: 'John',
married: true,
age: 25,
friends: ['Samuel', 'Kristian'],
children: [
{ name: 'Nency', age: 1 },
{ name: 'Peter', age: 10 },
],
company: {
name: 'Hexlet'
},
};
In this case, nested elements are accessed by chaining keys:
user.friends[1]; // 'Kristian'
user.children[0].name; // 'Nency'
user.company.name; // 'Hexlet'
There is one limitation built into console.log()
. If an object has nested objects deeper than the second level, when printing such an object, a string, [Object]
, will be displayed instead of the object itself, and another string, [Array]
, will be displayed instead of an array.
const obj = { a: { b: { c: { key: 'value' }, e: [1, 2] } } };
console.log(obj);
// { a: { b: { c: [Object], e: [Array] } } }
You can use the JSON conversion function to output such objects:
console.log(JSON.stringify(obj));
// {"a":{"b":{"c":{"key":"value"},"e":[1,2]}}}
// or formatted output
console.log(JSON.stringify(obj, null, ' '));
// {
// "a": {
// "b": {
// "c": {
// "key": "value"
// },
// "e": [
// 1,
// 2
// ]
// }
// }
// }
When working with nested objects, the task of checking that keys exist complicates dramatically. You have to build a chain of conditions for the desired property. Imagine we need to get to nesting level 4, and we're not certain that all the intermediate objects exist:
// Getting to obj.one.two.three
if (Object.hasOwn(obj, 'one')) {
if (Object.hasOwn(obj.one, 'two')) {
if (Object.hasOwn(obj.one.two, 'three')) {
// ...
}
}
}
This is what a head-on solution would look like. However, there is a more convenient way, which will be discussed below.
If the goal is to get the data and not just check that it exists, there is another way. JavaScript has a built-in optional chaining operator which allows you to extract nested data without any checks:
const obj = {};
obj?.one?.two?.three // undefined
This operator never causes an error. It works on any data type and always returns either undefined
or the property value if it exists.
With the nullish coalescing operator, you can do more than get a value in the chain at any nesting level, but also define a default value for it.
const obj = {};
obj?.one?.two?.three ?? 'defaultValue' // 'defaultValue'
The default value is only returned when undefined
or null
is on the left hand side. In this sense, this operator is not at all like the logical comparison ||
:
const value = false;
value ?? 'default'; // false
value || 'default'; // 'default'
The last example is overloaded with symbols and looks rather complicated. As an alternative, you can use the get()
function from the lodash library.
import _ from 'lodash';
const obj = {};
const value = _.get(obj, 'one.two.three', 'defaultValue'); // 'defaultValue'
get()
is especially useful for dynamic keys. In this case, you can pass an array of keys as the second argument:
_.get(obj, ['one', 'two', 'three'], 'defaultValue'); // 'defaultValue'
The Hexlet support team or other students will answer you.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
Sign up or sign in
Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.