Working with Objects
Working with Objects
Objects are the foundation of JavaScript. Nearly everything in JS is an object, and mastering the ways to create, access, and enumerate them will make you a significantly more effective developer.
Object Literals
An object literal is the most common way to create an object: a comma-separated list of key-value pairs enclosed in curly braces.
const person = {
name: "Alice",
age: 30,
greet() { return "Hi, I'm " + this.name; }
};Property Access
Use dot notation when the property name is a valid identifier known at write time, and bracket notation when the name is dynamic or not a valid identifier.
person.name // "Alice"
person["age"] // 30
const key = "name";
person[key] // "Alice"Shorthand Syntax
When a variable name matches the property name, you can use shorthand:
const name = "Bob";
const age = 25;
const obj = { name, age }; // same as { name: name, age: age }Computed Property Names
Bracket notation works in object literals too, allowing dynamic keys:
const prop = "color";
const car = { [prop]: "red" }; // { color: "red" }Object.keys / values / entries
These three static methods return arrays, making it easy to iterate or transform objects:
| Method | Returns |
|---|---|
| Object.keys(obj) | Array of own enumerable key strings |
| Object.values(obj) | Array of own enumerable values |
| Object.entries(obj) | Array of [key, value] pairs |
Object.assign & Object Spread
Object.assign(target, ...sources) copies properties into target (mutates it). Object spread { ...src } creates a shallow copy without mutation — prefer it in modern code.
Property Existence
"key" in obj checks own and inherited properties. Object.hasOwn(obj, "key") (ES2022) checks only own properties and is safer than the older obj.hasOwnProperty.
Deleting Properties
delete obj.prop removes a property. Avoid it in performance-critical code as it can de-optimize V8's hidden classes.
Code Examples
const product = {
id: 101,
name: "Laptop",
price: 999.99,
inStock: true,
specs: { ram: "16GB", storage: "512GB" },
};
// Dot notation
console.log(product.name);
console.log(product.specs.ram);
// Bracket notation with dynamic key
const field = "price";
console.log(product[field]);
// Shorthand and computed properties
const key = "discount";
const value = 0.1;
const promo = { ...product, [key]: value, name: "Gaming Laptop" };
console.log(promo.name, promo.discount);Dot notation is clean and readable. Bracket notation is necessary when the property name is stored in a variable. Computed property names let you set dynamic keys directly in an object literal.
const scores = { Alice: 92, Bob: 78, Carol: 85, Dave: 61 };
console.log("Keys: ", Object.keys(scores));
console.log("Values: ", Object.values(scores));
console.log("Entries:", Object.entries(scores));
// Iterate with for...of + destructuring
for (const [name, score] of Object.entries(scores)) {
const grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "D";
console.log(`${name}: ${score} (${grade})`);
}
// Convert entries back to object
const scaled = Object.fromEntries(
Object.entries(scores).map(([k, v]) => [k, v + 5])
);
console.log("Scaled:", scaled);Object.entries combined with for...of and destructuring is the most readable way to iterate over an object's key-value pairs. Object.fromEntries reconstructs an object from transformed entries.
const defaults = { theme: "light", fontSize: 14, lang: "en" };
const userPrefs = { theme: "dark", fontSize: 18 };
// Merge: userPrefs overrides defaults
const config = { ...defaults, ...userPrefs };
console.log(config);
// Object.assign — mutates the target
const target = { a: 1 };
Object.assign(target, { b: 2 }, { c: 3 });
console.log(target);
// Checking property existence
console.log("theme" in config); // true
console.log(Object.hasOwn(config, "theme")); // true
console.log(Object.hasOwn(config, "color")); // false
// delete a property
const obj = { x: 1, y: 2, z: 3 };
delete obj.y;
console.log(obj);Object spread is the modern way to create merged copies without mutation. Object.assign is useful when you must mutate a target. hasOwn is safer than in for checking own properties.
Quick Quiz
1. When must you use bracket notation to access an object property?
2. What does Object.entries({ a: 1, b: 2 }) return?
3. What is the shorthand property syntax for: const x = 5; const obj = { x: x };
Was this lesson helpful?