Object-Ception
Lesson objectives
After this lesson students will be able to:
- Use an array inside an object
- Iterate over an array that is within an object
- Use an object within an object
- Use an object within an object within an object
- Use an array within an object within an object within an object
- Use an array of objects
- Use variables to store a key
- Loop over an object
- Combine objects, arrays, and functions
Use an array inside an object
Let's model an adventurer who has belongings (a list)
const adventurer = {
name: "Timothy",
hitpoints: 10,
belongings: ["sword", "potion", "Tums"]
}
Access all values in the player.belongings array:
console.log(adventurer.belongings);
Access a specific item in the belongings array:
console.log(adventurer.belongings[0]);
Iterate over an array that is within an object
for (let i = 0; i < adventurer.belongings.length; i++) {
console.log(adventurer.belongings[i]);
}
Use an object within an object
Our adventurer now has a companion! Our companion, a bat, is an object with its own properties.
Add the companion object to the adventurer object:
const adventurer = {
name: "Timothy",
hitpoints: 10,
belongings: ["sword", "potion", "Tums"],
companion: {
name: "Velma",
type: "Bat"
}
}
Access the companion object:
console.log(adventurer.companion);
=> { name: "Velma", type: "Bat" }
Access the companion's name:
console.log(adventurer.companion.name);
=> "Velma"
Access the companion's type:
console.log(adventurer.companion.type);
=> "Bat"
Use an object within an object within an object
Velma the bat also has a companion, a magical parasite called Tim.
Let's add Tim to our data:
const adventurer = {
name: "Timothy",
hitpoints: 10,
belongings: ["sword", "potion", "Tums"],
companion: {
name: "Velma",
type: "Bat",
companion: {
name: "Tim",
type: "Parasite"
}
}
}
What would you write to:
console.logTim's type
Use an array within an object within an object within an object
Tim has a bag of holding and can carry an infinite number of belongings.
Let's add an array of belongings to Tim:
const adventurer = {
name: "Timothy",
hitpoints: 10,
belongings: ["sword", "potion", "Tums"],
companion: {
name: "Velma",
type: "Bat",
companion: {
name: "Tim",
type: "Parasite",
belongings: ["SCUBA tank", "Rogan josh", "health insurance"]
}
}
}
What would your write to:
console.log"health insurance"
Use an array of objects
A common pattern you will start to see everywhere (especially in Unit 2 and onwards) is an array of objects.
An array of objects can look like this:
const movies = [
{ title: "Tokyo Story" },
{ title: "Paul Blart: Mall Cop" },
{ title: "L'Avventura" },
];
These objects have no names, they are just anonymous objects packed into an array.
You could reference them with indexes as usual:
console.log(movies[0]);
You could reference the properties by first asking for the index, then the property:
console.log(movies[0].title);
You could loop over the array and just print all of the titles:
for (let i = 0; i < movies.length; i++) {
console.log(movies[i].title);
}
Use variables to store a key
const monster = {
name: "Slimer",
age: 6,
};
const someVar = "name";
console.log(monster[someVar]); // same as monster['name'];
=> 'Slimer'
Loop over an object
There are two way to loop over objects. You can use either way. Both ways involve looping over the object's keys.
Let's say we have a movie object:
const movie = {
title: "L'Avventura",
director: "Michelangelo Antonioni",
year: 1960,
};
for ... in loop
Print each key:
for (const key in movie) {
console.log(key);
}
=>
title
director
year
Print each value:
To do this, use the key as a variable within the square brackets.
for (const key in movie) {
console.log(movie[key]);
}
=>
L'Avventura
Michelangelo Antonioni
1960
Object.keys()
Object.keys() will return an array of keys
console.log(Object.keys(movie));
=> [ 'title', 'director', 'year' ]
To print the values, use the key as a variable within square brackets.
const keys = Object.keys(movie);
for (let i = 0; i < keys.length; i++) {
console.log(movie[keys[i]]);
}
Combine objects, arrays, and functions
You can create a property for an object that is an array
const foo = {
someArray:[1,2,3]
};
foo.someArray[0]; //1
You can create a property for an object that is an object
const foo = {
someObject: {
someProperty: 'oh hai!'
}
};
foo.someObject.someProperty; //oh hai!
You can create a property for an object that is a function (method)
const foo = {
someMethod: () => {
console.log("oh hai");
},
};
foo.someMethod(); //logs 'oh hai!'
You can store an object in an array
const foo = [{ someProperty: "weee" }, 2, 3];
console.log(foo[0].someProperty);
You can store an array in an array
const foo = [
["0,0", "0,1", "0,2"],
["1,0", "1,1", "1,2"],
["2,0", "2,1", "2,2"],
];
foo[1][2]; //1,2
You can store a function in an array
const foo = [
1,
"hi",
() => {
console.log("fun");
},
];
foo[2]();
Optional chaining (?.) Elvis Operator
The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.
The ?. operator is like the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.
const adventurer = {
name: "Alice",
cat: {
name: "Dinah",
},
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined
console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined