Objects are the most important data structure in JavaScript. Almost everything in JS is an object or behaves like one. In simple language, an object is just a collection of key-value pairs — we call them properties. When a property’s value is a function, we call it a method.
Creating objects (object literals)
The simplest way to create an object is with curly braces. This is called an object literal:
const user = {
name: "Manish",
age: 25,
greet() { // shorthand method syntax
console.log(`Hi, I'm ${this.name}`);
}
};
That’s it. No class needed, no constructor — just a plain object.
Dot notation vs bracket notation
We have two ways to access properties:
console.log(user.name); // "Manish" — dot notation
console.log(user["name"]); // "Manish" — bracket notation
Dot notation is cleaner, but bracket notation is more powerful — we can use variables and strings with spaces or special characters:
const key = "age";
console.log(user[key]); // 25 — dynamic access
const weird = { "full name": "Manish P" };
console.log(weird["full name"]); // bracket notation is required here
Computed property names
ES6 lets us use expressions as property names inside the object literal using square brackets:
const field = "email";
const profile = {
[field]: "manish@example.com", // key becomes "email"
[`${field}Verified`]: true // key becomes "emailVerified"
};
Shorthand syntax
When the variable name matches the property name, we can skip the colon:
const name = "Manish";
const age = 25;
const user = { name, age }; // same as { name: name, age: age }
Object.keys, Object.values, Object.entries
These three static methods are super handy for iterating over objects:
const car = { brand: "Toyota", year: 2022, color: "white" };
Object.keys(car); // ["brand", "year", "color"]
Object.values(car); // ["Toyota", 2022, "white"]
Object.entries(car); // [["brand", "Toyota"], ["year", 2022], ["color", "white"]]
Object.entries is especially useful with for...of loops or when we want to convert an object into a Map.
Object.freeze vs Object.seal
Both lock down an object, but in different ways:
Object.freeze()— no adding, removing, or modifying properties. The object becomes completely immutable (shallow).Object.seal()— no adding or removing properties, but we can modify existing ones.
const frozen = Object.freeze({ x: 1 });
frozen.x = 99; // silently fails (or throws in strict mode)
console.log(frozen.x); // 1
const sealed = Object.seal({ x: 1 });
sealed.x = 99; // this works!
sealed.y = 2; // silently fails — can't add new properties
console.log(sealed.x); // 99
One gotcha — both are shallow. Nested objects inside a frozen object can still be modified.
Object.assign
Object.assign copies properties from one or more source objects into a target object. It’s commonly used for merging objects or creating shallow copies:
const defaults = { theme: "dark", lang: "en" };
const userPrefs = { lang: "hi" };
const config = Object.assign({}, defaults, userPrefs);
console.log(config); // { theme: "dark", lang: "hi" }
These days, most of us prefer the spread operator { ...defaults, ...userPrefs } — it does the same thing and looks cleaner.
Checking if a property exists
We have two common approaches:
The in operator checks the object and its entire prototype chain:
const user = { name: "Manish" };
console.log("name" in user); // true
console.log("toString" in user); // true — inherited from Object.prototype
hasOwnProperty() only checks the object’s own properties (not inherited ones):
console.log(user.hasOwnProperty("name")); // true
console.log(user.hasOwnProperty("toString")); // false — it's inherited
The modern alternative is Object.hasOwn(obj, prop) which does the same thing as hasOwnProperty but works even if the object doesn’t have that method in its prototype.
Deleting properties
We can remove a property with the delete operator:
const obj = { a: 1, b: 2 };
delete obj.b;
console.log(obj); // { a: 1 }
delete returns true if the deletion succeeds. It doesn’t affect the prototype chain — only own properties.
In simple language, objects are just bags of key-value pairs. We create them with {}, access properties with dot or bracket notation, and use built-in methods like Object.keys(), Object.freeze(), and Object.assign() to work with them. Master these basics, and everything else in JavaScript OOP builds on top of this.