Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

JavaScript objects are more than bags of values: property lookup can reach a prototype, enumeration methods include different sets of keys, and freezing an object does not automatically freeze objects nested inside it. These five points explain how to access, inspect, and control object properties without confusing direct properties with inherited ones.

1. An object associates property names with values

An object is a collection of properties. Each property associates a name, also called a key, with a value. For example, this object has an own property named name whose value is the string "Rae":

const user = { name: "Rae" };

A property’s value can also be a function. A function stored on an object is commonly called a method.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For an introduction to object literals and properties, see MDN’s guide to working with objects.

2. Dot and bracket notation access properties in different situations

Use dot notation when the property name is a valid identifier and known in the code. Bracket notation accepts a property key as an expression, so it works when the key is stored in a variable or when the name cannot be written as a dot-notation identifier.

const user = { name: "Rae", "preferred-language": "English" };
const field = "name";

user.name;                 // "Rae"
user["name"];              // "Rae"
user[field];               // "Rae"
user["preferred-language"]; // "English"

Bracket notation is useful for dynamic access, but take care when a key comes from untrusted input: accessing a property and assigning to one are different operations, and assignments can change the object.

New objects normally inherit from a prototype. To choose a prototype explicitly, use Object.create(proto); passing null creates an object with no prototype:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const record = Object.create(null);

This can be useful for a dictionary-like object that should not inherit names such as toString. It also means the object does not inherit methods from Object.prototype. See MDN’s object guide for property access and object creation details.

3. A property can be available without belonging directly to the object

When JavaScript looks up a property, it first checks the object itself and then follows its prototype chain if necessary. As a result, a property can be accessible through an object without being one of its own properties. An own property can also shadow a property with the same name on the prototype.

Use Object.hasOwn(obj, key) to ask whether a property belongs directly to the object. Use the in operator to ask whether the property exists on the object or anywhere on its prototype chain:

const user = { name: "Rae" };

"toString" in user;               // true: found through the prototype chain
Object.hasOwn(user, "toString");  // false: not an own property
Object.hasOwn(user, "name");      // true

Most ordinary objects inherit from Object.prototype, which is why names such as toString may be found even when they were not written in an object literal. Prefer Object.hasOwn for direct-ownership checks; unlike calling obj.hasOwnProperty(key), it still works if the object has a property that shadows that method. The distinctions are documented in MDN’s guide to enumerability and property ownership and the MDN Object reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Enumeration methods return different sets of properties

“Loop over an object” can mean different things depending on which properties you need. The methods below differ along three axes: whether they include inherited properties, whether they include non-enumerable properties, and whether they include symbol keys.

Method Own or inherited Enumerable or non-enumerable String or symbol keys What it returns
Object.keys(obj) Own only Enumerable only String keys only An array of matching keys
Object.values(obj) Own only Enumerable only Values of matching string-keyed properties An array of values
Object.entries(obj) Own only Enumerable only String keys only An array of key-value pairs
for...in Own and inherited Enumerable only String keys only Each matching key in turn
Reflect.ownKeys(obj) Own only Enumerable and non-enumerable String and symbol keys An array of all own keys

For a plain record’s enumerable own string keys, Object.keys is often the clearest choice. If using for...in but wanting only direct properties, check each key with Object.hasOwn:

for (const key in user) {
  if (Object.hasOwn(user, key)) {
    // Handle this own, enumerable string key.
  }
}

Use Reflect.ownKeys when you need every own key, including symbols and non-enumerable properties. Other property-inspection APIs, such as symbol-specific or descriptor APIs, can help when you need to inspect a particular category. See MDN’s property enumeration guide.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

5. Freezing an object does not freeze its nested objects

Object.freeze(obj) prevents adding or removing properties and changing existing property descriptors or data-property values on that object. It is a shallow operation: a property that refers to another object still refers to a separately mutable object.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const settings = Object.freeze({ display: { theme: "light" } });

settings.display.theme = "dark"; // The nested object is not frozen by this call.

If nested objects must also be frozen, freeze those objects separately. Freezing only the outer object does not make an entire object tree immutable. Read the details and limitations in MDN’s Object.freeze() reference.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.