Course outline · 0% complete

0/29 lessons0%

Course overview →

Objects: labeled data

lesson 5-1 · ~9 min · 14/29

Data with labels instead of positions

Lesson 4-2 built a shopping list with push, and covered a method that does two jobs at once: list.pop() removes the last item and returns it, so const last = list.pop() both shrinks the array and captures the value that left. Its counterpart at the other end is shift().

Arrays like that one are the right tool when every item plays the same role and the position carries the meaning. This unit covers the other shape of data, where each piece means something different and needs a name rather than a number.

Objects are JavaScript's dictionaries

Arrays handle many of the same thing, while objects handle one thing with many facts. A user has a name, an age, and a plan. A product has a title and a price. Nearly every piece of data a server will ever send you, which is the subject of lesson 5-3, arrives in this shape, so reading and writing it has to become reflex.

An array numbers its items. An object names them. It is JavaScript's version of the Python dict you used for labeled data:

const user = {
  name: "Ada",
  age: 36,
  premium: true
};

Each name: value pair is a property. Unlike Python dicts, the keys are written without quotes, though quotes are allowed and become necessary for keys with unusual characters.

Reading has two spellings:

  • Dot notation, the everyday one: user.name
  • Bracket notation, for keys stored in variables or keys with odd characters: user["age"] or user[someKey]

Writing works the same way. Assigning to a property that does not exist yet simply creates it, and delete user.premium removes one. As with arrays, a const object can still have its contents changed, because const only locks the name.

Reading, updating, and adding properties

Four things happen here in sequence: two reads with the two different notations, an update to an existing property, and the creation of a brand new one.

const user = {
  name: "Ada",
  age: 36,
  premium: true
};

console.log(user.name);
console.log(user["age"]);

user.age = 37;
user.country = "UK";
console.log(user.age);
console.log(user);

Output

Ada
36
37
{ name: 'Ada', age: 37, premium: true, country: 'UK' }

user.name and user["age"] are equally valid ways to read a property, and here they differ only in style. The interesting pair is user.age = 37 against user.country = "UK". Both are plain assignments, and the language decides between updating and creating based on whether the property already existed. Nothing announces that a new property is being added.

Printing the whole object at the end shows the result, with country sitting at the end because properties keep the order in which they were added.

Building a book object and extending it

A small object created with two properties, read back inside a template literal, then given a third property after the fact.

const book = { title: "Dune", pages: 412 };

console.log(`${book.title} has ${book.pages} pages`);

book.author = "Frank Herbert";
console.log(book.author);

Output

Dune has 412 pages
Frank Herbert

Short objects like this one fit comfortably on a single line, and the pairs are separated by commas exactly as they are in the multi-line form. Inside the template literal from lesson 1-3, the placeholders hold full property lookups, since ${...} accepts any expression and book.title is one.

Adding author afterwards is nothing more than assignment. There is no separate command for growing an object, which is convenient and also a hazard: a misspelled book.pagse = 500 quietly creates a second property rather than complaining.

Reading a property whose name is in a variable

With const key = "email"; in hand, the expression that reads that property is user[key].

The two notations differ in when the name is decided. user.key looks for a property literally called key, since a dot takes the word written after it at face value, and here that property does not exist, so the result is undefined. Bracket notation evaluates whatever sits inside the brackets first, so user[key] becomes user["email"] and finds the real property.

NotationProperty looked upUse it for
user.emailemailnames you know while writing the code
user[key]whatever key holdsnames decided while the program runs
user["sign-up date"]sign-up datenames with spaces, dashes, or digits first

The rule in one line: dots for names you type, brackets for names your program computes.