Object Literals & Properties

Intermediate · 18 min read · ▶ live playground · ✦ checkpoint

Arrays are great when position matters: first score, second score, last score. Objects are how JavaScript keeps named facts together: a player's name, score, rank, and settings all living in one value. An object literal is the { ... } form that creates that kind of grouped value directly in your code.

Objects group named properties

An object is a small bundle of properties. A property is a name-value pair: the name is the key, and the value is whatever that key points to.

const player = {
  name: "Mina",
  score: 12,
  isMember: true,
};
 
console.log(player.name);
console.log(player.score);
console.log(player.isMember);

Mina, 12, true.

Read this like a labeled card:

  • name is the label; "Mina" is the value behind it.
  • score is the label; 12 is the value behind it.
  • isMember is the label; true is the value behind it.

The commas matter because each property is a separate entry in the object. This course also uses a final trailing comma in multi-line objects. JavaScript allows it, and it makes future edits cleaner.

Objects can hold any value you already know: strings, numbers, booleans, undefined, null, arrays, and even other objects. Functions can also live in properties, but those become methods, and lesson 7.3 gives that pattern its own treatment.

Dot access vs bracket access

Most of the time, use dot access: object.property. It is short, readable, and says exactly which property you want.

const player = {
  name: "Mina",
  score: 12,
  "favorite color": "teal",
};
 
const field = "score";
 
console.log(player.name);
console.log(player.score);
console.log(player["favorite color"]);
console.log(player[field]);
console.log(player.field);

Mina, 12, teal, 12, then undefined.

Bracket access has two jobs:

  • Use player["favorite color"] when the property name is not a normal identifier, such as a name with a space or dash.
  • Use player[field] when the property name is stored in a variable.

The last line is the classic reading mistake. player.field asks for a property literally named field. It does not look inside the variable named field. If you want the value of the variable to choose the property, use brackets.

Reading a missing property gives undefined. That is why player.field prints undefined instead of crashing.

Add, update, and delete properties

Objects are usually stored in const variables, and their properties can still change. You saw the same binding-vs-value idea with arrays: const protects the name from being reassigned, not every piece inside the object.

const player = {
  name: "Mina",
  score: 12,
};
 
player.rank = "silver";
player.score = player.score + 5;
delete player.rank;
 
console.log(player.name);
console.log(player.score);
console.log(player.rank);

Mina, 17, then undefined.

Assigning a new property creates it. Assigning an existing property updates it. delete object.property removes the property, so reading it afterward gives the same answer as any missing property: undefined.

Use delete when the absence of the property means something. If a property still belongs on the object but has no value yet, setting it to null can communicate "intentionally empty" more clearly. The deeper reference and mutation story is coming in 7.4; for now, keep the surface rule: property assignment changes the object.

Try it — read the right label

Run this once, then change field from "score" to "rank". At the prompt, try player.name, player[field], and player.inventory.

javascript — live consolereal engine
⌘/Ctrl + Enter to run

The object is still one value, but you are now choosing labels in three different ways: dot access for fixed names, bracket access for a quoted name, and bracket access with a variable for a dynamic choice.

Shorthand properties and computed keys

Object literals have two everyday shortcuts.

The first is property shorthand. When your variable name and property name match, write the name once:

const name = "Mina";
const score = 18;
 
const player = {
  name,
  score,
  rank: "gold",
};
 
console.log(player.name);
console.log(player.score);
console.log(player.rank);

Mina, 18, gold.

name inside the object means name: name. score means score: score. The shorthand is not magic; it is a less noisy spelling for the same property pair.

The second shortcut is a computed key: a property name calculated inside brackets while the object is being created.

const statName = "bonusPoints";
const bonus = 5;
 
const player = {
  name: "Mina",
  [statName]: bonus,
};
 
console.log(player.bonusPoints);
console.log(player[statName]);

5, then 5.

Computed keys are useful when the property name comes from earlier code: a selected report column, a setting name, a grouping label, or a form field name in a future browser lesson. Keep them readable. If the key calculation gets long, name it first with const, then use that name inside the object.

Nested objects and safe access

A nested object is an object inside another object. Read it one label at a time, left to right.

const player = {
  name: "Mina",
  stats: {
    highScore: 42,
    streak: 7,
  },
};
 
console.log(player.stats.highScore);
console.log(player.stats.streak);

42, then 7.

The danger is assuming every middle property exists. This code fails because stats is missing, so JavaScript cannot keep walking to .highScore:

const player = {
  name: "Rae",
};
 
console.log(player.stats.highScore);

V8 reports TypeError: Cannot read properties of undefined (reading 'highScore'). The safer read is optional chaining, written with ?.: continue only if the value on the left is not null or undefined.

const player = {
  name: "Rae",
};
 
console.log(player.stats?.highScore);
console.log(player.stats?.highScore ?? 0);

undefined, then 0.

player.stats?.highScore says: if player.stats exists, read .highScore; otherwise give back undefined. The ?? 0 part is the nullish default from Section 4: if the safe read produced null or undefined, use 0 instead.

Use optional chaining when missing data is a normal possibility. Do not use it to hide a shape your program actually requires. If every player must have stats, a missing stats object is a bug you should notice.

Checkpoint

Answer all three to mark this lesson complete

You can now model data by name instead of by position: object literals, property access, property changes, computed keys, and safe reads through nested shapes. Next, 7.2 teaches destructuring, spread, and rest so you can pull properties out, copy object shapes, and collect "everything else" without repetitive access code.

+50 XP on completion