Object Properties in JavaScript

Introduction

Working with objects means reading, writing, and sometimes removing properties safely. This chapter covers dot and bracket access, computed keys, optional chaining, and patterns for updating nested data—skills you use in every API client and form handler.

Prerequisites

Reading Properties

javascript
// Read with dot and bracket
const user = { id: 7, name: "Ada", role: "admin" };
 
console.log(user.name);
console.log(user["role"]);

Safe read when data may be missing:

javascript
// Optional chaining
const profile = { user: { name: "Lin" } };
console.log(profile.user?.name);
console.log(profile.manager?.name);

Writing and Updating

javascript
// Update existing keys
const account = { balance: 100 };
account.balance = 150;
account.currency = "USD";
 
console.log(account);

Bracket notation for dynamic keys:

javascript
// Dynamic property name
const key = "lastLogin";
const session = { userId: 1 };
session[key] = "2026-05-20";
console.log(session);

Computed Property Names (Literals)

javascript
// Key from variable in literal
const field = "status";
const task = {
  id: 10,
  [field]: "done",
  [`${field}At`]: Date.now(),
};
 
console.log(task);

Nested Updates (Immutability-Friendly)

Avoid mutating nested shared data accidentally:

javascript
// Shallow spread for one level of update
const state = {
  user: { name: "Ada", prefs: { theme: "light" } },
};
 
const nextState = {
  ...state,
  user: {
    ...state.user,
    prefs: { ...state.user.prefs, theme: "dark" },
  },
};
 
console.log(state.user.prefs.theme);
console.log(nextState.user.prefs.theme);

Deleting Properties

javascript
// delete operator
const cache = { a: 1, b: 2, temp: true };
delete cache.temp;
console.log(cache);

delete only affects own properties; use carefully in hot paths.

Testing Whether a Property Exists

javascript
// in operator and hasOwnProperty
const data = { name: "Sam", age: 0 };
 
console.log("name" in data);
console.log("toString" in data);
console.log(Object.hasOwn(data, "age"));
console.log(Object.hasOwn(data, "toString"));
  • in: checks the chain (including inherited)
  • Object.hasOwn: own properties only (modern replacement for hasOwnProperty)

Tip

Best Practice

Use Object.hasOwn(obj, key) when you care about own keys. Use optional chaining when you only need safe reads.

Enumerating Keys

javascript
// Object.keys, values, entries
const scores = { math: 90, english: 88 };
 
console.log(Object.keys(scores));
console.log(Object.values(scores));
console.log(Object.entries(scores));

Mini Example: Patch API Response

javascript
// Normalize API user payload
const apiUser = {
  id: "u-42",
  display_name: "Ada",
  is_active: true,
};
 
const viewModel = {
  id: apiUser.id,
  name: apiUser.display_name,
  active: apiUser.is_active,
};
 
if (Object.hasOwn(apiUser, "avatar_url")) {
  viewModel.avatarUrl = apiUser.avatar_url;
}
 
console.log(viewModel);

FAQ

Is obj.key the same as obj["key"]?

Yes when key is a valid identifier literal. Use brackets for variables and special names.

What about obj?.key = value?

Optional chaining is for reads and calls, not assignment targets.

How do I deep clone?

structuredClone(obj) in modern environments, or libraries for complex graphs.

What comes next?

Extending and copying objects and JSON serialization.