Accessing Object Properties in JS: Full Tutorial

Learn how to read, update, and safely access JavaScript object properties using dot notation, bracket notation, optional chaining, and dynamic keys.

6 min read

Accessing an object property means reading or updating a specific value inside an object. JavaScript gives you two direct syntaxes for this (dot notation and bracket notation), plus a safer way to reach nested values with optional chaining.

Choose the right access style based on whether you know the property name ahead of time, whether it comes from a variable, and how deeply nested the object is.

Dot Notation

Dot notation is the most common way to access object properties. Write the object name, a dot, then the property name:

javascriptjavascript
const user = {
  name: "Jordan",
  age: 24,
  city: "Seattle"
};
 
console.log(user.name); // "Jordan"
console.log(user.age);  // 24

To update a property, you assign a new value using the same dot notation on the left side of an equals sign. This works the same way as creating a property:

javascriptjavascript
user.age = 25;
user.city = "Portland";
 
console.log(user.age);  // 25
console.log(user.city); // "Portland"

Dot notation is short and readable. Use it whenever the property name is a valid JavaScript identifier: no spaces, no special characters, and not starting with a number.

If the property does not exist, JavaScript returns undefined instead of throwing an error:

javascriptjavascript
console.log(user.country); // undefined

Bracket Notation

Bracket notation uses square brackets with a string or expression inside. It is required when the property name is dynamic, contains special characters, or starts with a number:

javascriptjavascript
const data = {
  "full name": "Taylor Kim",
  "1st-place": true,
  "user-id": 9002
};
 
console.log(data["full name"]);  // "Taylor Kim"
console.log(data["1st-place"]);  // true
console.log(data["user-id"]);    // 9002

Dot notation would fail here because a name with a space, a leading digit, or a dash is not a valid JavaScript identifier.

Dynamic Property Access

The real power of bracket notation is that you can use a variable, a function call, or any expression that evaluates to a string:

javascriptjavascript
const product = {
  name: "Laptop",
  price: 999,
  category: "Electronics"
};
 
const field = "price";
console.log(product[field]); // 999

The variable field holds the string "price", and bracket notation reads whatever that variable currently contains. This same pattern scales to a loop when you need to read several properties in a row:

javascriptjavascript
const fields = ["name", "price", "category"];
 
for (const key of fields) {
  console.log(key + ": " + product[key]);
}

The loop reads each string in the fields array, then uses it as a bracket key to pull the matching value straight off the product object, printing one line per property:

texttext
name: Laptop
price: 999
category: Electronics

This lets you loop through properties or look up values based on user input, API field names, or configuration objects. You cannot do this with dot notation because it would look for a literal property named field, not the value stored in the variable of the same name.

You can also compute keys with expressions:

javascriptjavascript
const prefix = "user";
console.log(product[prefix + "Id"]); // Looks for product.userId

Optional Chaining (?. )

Deeply nested objects are common when working with API responses or configuration. Accessing a property on undefined or null throws a TypeError:

javascriptjavascript
const response = {};
 
// This throws: Cannot read properties of undefined
// console.log(response.user.address.city);

Optional chaining, added in ES2020, solves this. Use ?. instead of a plain dot when a value might be null or undefined:

javascriptjavascript
const response = {};
 
console.log(response.user?.address?.city); // undefined (safe)

If any part of the chain is null or undefined, the whole expression short-circuits and returns undefined instead of throwing.

With a real object it works like normal dot notation:

javascriptjavascript
const response = {
  user: {
    address: { city: "Berlin" }
  }
};
 
console.log(response.user?.address?.city); // "Berlin"

Optional chaining also works with bracket notation and function calls, which matters when a value might be missing but you still need to look up a computed key or call a method that may not exist:

javascriptjavascript
const data = null;
 
console.log(data?.["key"]);  // undefined
console.log(data?.method()); // undefined

For a deeper treatment of safe property access chains, see the article on /javascript/javascript-optional-chaining-complete-guide.

Checking If a Property Exists

Since accessing a nonexistent property returns undefined, you might use a simple truthiness check. But this can be misleading if the property is set to undefined on purpose:

javascriptjavascript
const config = { volume: 0, theme: undefined };
 
console.log(config.volume);     // 0 (falsy, but exists)
console.log(config.theme);      // undefined (exists but set to undefined)
console.log(config.language);   // undefined (does not exist)

Use the in operator to reliably check for existence instead, since it looks at the key itself rather than the value stored inside it, so a property set to undefined still counts as present:

javascriptjavascript
console.log("volume" in config);   // true
console.log("theme" in config);    // true
console.log("language" in config); // false

hasOwnProperty() is stricter than in: it checks only the object itself, ignoring inherited properties from the prototype, so it will not falsely report a built-in method as one of your own keys:

javascriptjavascript
console.log(config.hasOwnProperty("volume"));    // true
console.log(config.hasOwnProperty("toString"));  // false (inherited)

For most beginner code, in is sufficient and shorter.

Object Destructuring

Destructuring lets you pull multiple properties into separate variables in one clean statement:

javascriptjavascript
const book = {
  title: "Eloquent JavaScript",
  author: "Marijn Haverbeke",
  year: 2018
};
 
const { title, author } = book;
 
console.log(title);  // "Eloquent JavaScript"
console.log(author); // "Marijn Haverbeke"

You can also rename the extracted variable and give it a default value, which is useful when the source object might not include every property you expect:

javascriptjavascript
const { title: bookTitle, rating = 5 } = book;
 
console.log(bookTitle); // "Eloquent JavaScript"
console.log(rating);    // 5 (default, book has no rating property)

Destructuring is especially useful when a function takes an options object. For more patterns, see the article on /javascript/javascript-object-destructuring-complete-guide.

Common Mistake: Dot Notation with Variables

A frequent beginner error is using dot notation with a variable, expecting JavaScript to use the variable's value:

javascriptjavascript
const key = "name";
const obj = { name: "Casey" };
 
console.log(obj.key);  // undefined (looks for literal property "key")
console.log(obj[key]); // "Casey" (correct -- uses the variable's value)

Dot notation always treats the word after the dot as a literal property name. If you need to look up a property whose name is stored in a variable, use bracket notation.

Choosing the Right Access Method

When to useSyntax
Property name is known and a valid identifierobj.name
Property name is in a variableobj[variable]
Property name has spaces or special charactersobj["full name"]
Property name is computed or dynamicobj["prefix" + id]
Nested path might be null or undefinedobj?.nested?.value
Extracting multiple properties at onceconst { a, b } = obj
Rune AI

Rune AI

Key Insights

  • Use dot notation for static, known property names: obj.name.
  • Use bracket notation when the key is in a variable, contains special characters, or is computed.
  • Optional chaining (?.) safely accesses nested properties without throwing on null or undefined.
  • Accessing a nonexistent property returns undefined -- use the in operator to check if a property truly exists.
  • Destructuring gives you a clean way to pull multiple properties into variables in one line.
RunePowered by Rune AI

Frequently Asked Questions

What happens if I access a property that does not exist?

JavaScript returns undefined. It does not throw an error unless you try to access a property on undefined or null itself, which is where optional chaining helps.

Can I use a variable to access an object property?

Yes. Use bracket notation with the variable: obj[variableName]. Dot notation does not work with variables because it treats the name literally.

What is the safest way to access deeply nested properties?

Use optional chaining: obj?.nested?.value. It returns undefined if any part of the chain is null or undefined instead of throwing an error.

Conclusion

You have two main tools for accessing object properties: dot notation for static, known property names and bracket notation for dynamic keys, special characters, or computed lookups. Add optional chaining when you need safe deep access. Knowing when to use each tool makes your object code safer and more readable.