Objects are JavaScript's universal container — every API response, config and component prop is one. The modern syntax around them (destructuring, spread, ?.) is half of what makes JS pleasant now.
Create with braces: const user = { name: "Ada", age: 12 }. Read with user.name or user["name"]. Pull values out with destructuring: const { name, age } = user. Reach into maybe-missing data safely with user?.profile?.bio.
const user = {
name: "Ada",
age: 12,
langs: ["python", "js"],
greet() { return `Hi, I'm ${this.name}`; } // method shorthand
};
console.log(user.name); // dot — when you know the key
const key = "age";
console.log(user[key]); // bracket — dynamic keys
user.level = 3; // add anytime
delete user.age; // removeconst player = { name: "Ada", hp: 100, pos: { x: 4, y: 7 } };
const { name, hp } = player; // pull out two fields
const { hp: health = 50 } = player; // rename + default
const { pos: { x, y } } = player; // nested
function intro({ name, hp }) { // destructure parameters!
return `${name} (${hp} HP)`;
}const defaults = { theme: "dark", lang: "en" };
const prefs = { lang: "ur" };
const settings = { ...defaults, ...prefs }; // later wins
// { theme: "dark", lang: "ur" }
const copy = { ...settings }; // shallow copy
const deep = structuredClone(settings); // real deep copy (modern)const res = { data: { user: null } };
// old way: res.data && res.data.user && res.data.user.name
const name = res.data?.user?.name; // undefined, no crash
const safe = res.data?.user?.name ?? "Guest"; // with default
res.onDone?.(); // call a function only if it existsconst player = { name: "Ada", level: 7 };
const text = JSON.stringify(player); // object → string
// '{"name":"Ada","level":7}'
const back = JSON.parse(text); // string → object
localStorage.setItem("save", JSON.stringify(player));
const loaded = JSON.parse(localStorage.getItem("save") ?? "{}");Dot (user.name) needs a literal key name; brackets (user[key]) accept any expression — required for dynamic keys or keys with spaces.
Nullish coalescing: a ?? b returns b only when a is null or undefined — unlike ||, it keeps valid falsy values like 0 and "".
JSON is a text format (always a string, double-quoted keys, no functions); an object is live in-memory data. stringify/parse convert between them.
for (const [key, value] of Object.entries(obj)) — or Object.keys(obj)/Object.values(obj) for just one side.