Skip to main content

Object-Ception

Lesson objectives

After this lesson students will be able to:

  1. Use an array inside an object
  2. Iterate over an array that is within an object
  3. Use an object within an object
  4. Use an object within an object within an object
  5. Use an array within an object within an object within an object
  6. Use an array of objects
  7. Use variables to store a key
  8. Loop over an object
  9. 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.log Tim'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