An Object Is a Bag of Named Values
An array groups values by position. An object groups them by name. When the thing you're modelling has labelled parts — a user with a name and an age, a request with a method and a URL — reach for an object.
The shortest way to make one is an object literal:
Each entry is a key: value pair. Keys are strings under the hood (quotes optional for valid identifiers like name). Values can be anything JavaScript knows how to represent — numbers, strings, booleans, arrays, functions, even other objects.
Trailing comma after the last entry is fine. Most teams leave it in — it keeps diffs clean when you add a new property later.
Reading and Writing Properties
Two ways to access a property: dot notation and bracket notation.
Dot notation is tidier and what you'll reach for by default. Bracket notation earns its keep when the key is stored in a variable, or when the key isn't a valid identifier:
Reading a property that doesn't exist returns undefined — no error:
That can silently paper over typos. If you want a loud failure, you'll need to check for it explicitly.
Adding and Deleting Properties
Objects are open for business — you can add keys any time:
And remove them with delete:
delete is one of those operators you won't use every day, but when you need to drop a key entirely (not just set it to undefined), it's the right tool. Setting user.email = undefined keeps the key around — "email" in user would still be true.
Checking if a Property Exists
Three ways, each with a slightly different meaning:
inchecks whether the key exists, including ones inherited from the prototype chain.Object.hasOwn(obj, key)checks only the object's own keys. Use this when you want to ignore inherited stuff. It replaces the olderhasOwnPropertycall.obj.key !== undefinedworks most of the time but lies when a property is explicitly set toundefined.
Pick Object.hasOwn when you're not sure — it does what you probably mean.
Methods: Functions That Live on Objects
A property whose value is a function is a method. There's a short syntax for defining them inside an object literal:
this inside a method refers to the object the method was called on — user in this case. That's how greet knows whose name to use.
One thing to watch: arrow functions don't have their own this, so they're the wrong choice for methods that need to read other properties of the object:
Use the shorthand method syntax (greet() { ... }) for anything that touches this. Arrow functions are great for callbacks, not for object methods.
Nested Objects
Values can be objects too, all the way down:
Reading a nested property works by chaining — user.address.city. The catch: if any step along the way is null or undefined, you get a TypeError:
console.log(user.profile.city);
// TypeError: Cannot read properties of undefined (reading 'city')
Optional chaining (user.profile?.city) is the modern fix — it returns undefined instead of throwing when a link is missing. There's a dedicated page on that later in this chapter.
Looping Through an Object
When you need to walk every key in an object, the Object.keys, Object.values, and Object.entries family is what you want:
Object.entries is the most useful — it gives you both the key and the value at once, and pairs nicely with array destructuring.
There's also a for...in loop, but it walks inherited properties too, which is usually not what you want:
for (const key in scores) {
console.log(key); // works, but includes inherited keys
}
Prefer Object.keys / Object.entries unless you specifically want inherited properties.
Shorthand Syntax Worth Knowing
Two pieces of syntactic sugar you'll see everywhere:
Property shorthand triggers when the variable name matches the key. Computed keys (the [expr] form) let you build property names dynamically — useful when writing functions that update a field by name.
Object Equality Is by Reference
This trips up almost everyone once:
=== on objects checks whether both sides refer to the same object in memory, not whether they have the same contents. Two objects with identical properties are still two different objects.
For "do these have the same shape?" you'll need to compare fields manually, or use a deep-equality helper. JSON.stringify(a) === JSON.stringify(b) is a quick-and-dirty check that works for plain data but falls over on anything with functions, undefined, or circular references.
Objects Are Mutable Even With const
const locks the variable to one value. It doesn't freeze the object that value points at:
If you actually want immutability, Object.freeze(user) stops further changes (shallowly — nested objects still mutate). In practice, most code leans on convention rather than Object.freeze — treat const objects as "don't reassign this binding" and handle immutability at the design level.
Next: Arrays
Objects and arrays are the two building blocks everything else is made of. Objects handle labelled data; arrays handle ordered data. Up next: how JavaScript arrays work, and the handful of methods (push, slice, map, and friends) that do most of the heavy lifting.
Frequently Asked Questions
How do you create an object in JavaScript?
The usual way is an object literal: const user = { name: 'Ada', age: 30 }. The braces hold key-value pairs separated by commas. Keys are strings (quotes optional for valid identifiers), and values can be anything — numbers, strings, arrays, functions, other objects.
What's the difference between dot and bracket notation?
user.name and user['name'] do the same thing when the key is a known identifier. Use brackets when the key is stored in a variable (user[key]), contains characters dot notation can't parse (spaces, hyphens), or starts with a digit. Dot notation is tidier for everything else.
How do you check if a property exists on an object?
Use 'name' in user to check for the key, including inherited ones. Use Object.hasOwn(user, 'name') to check only the object's own properties — it's the modern replacement for hasOwnProperty. Checking user.name !== undefined works too, but lies if the property is explicitly set to undefined.
How do you loop through an object in JavaScript?
for (const key in obj) iterates keys, including inherited ones. More commonly, use Object.keys(obj), Object.values(obj), or Object.entries(obj) with a for...of loop or .forEach(). Object.entries is handy when you need both the key and the value in the same iteration.