18 minLesson 15 of 35
Arrays & Objects
Object Methods & Iteration
Object Methods & Iteration
JavaScript objects are the foundation of almost everything you work with. Knowing how to iterate, transform, and inspect them programmatically is essential for API work, data processing, and writing clean code.
Object.keys, Object.values, Object.entries
These three methods convert objects into arrays so you can use array methods on them:
const product = { name: "Widget", price: 9.99, stock: 150, active: true };
Object.keys(product); // ["name", "price", "stock", "active"]
Object.values(product); // ["Widget", 9.99, 150, true]
Object.entries(product); // [["name","Widget"], ["price",9.99], ["stock",150], ["active",true]]
// Iterate with for...of + entries
for (const [key, value] of Object.entries(product)) {
console.log(`${key}: ${value}`);
}
// Transform all values
const rounded = Object.fromEntries(
Object.entries(product).map(([k, v]) => [k, typeof v === 'number' ? Math.round(v) : v])
);
// Filter out falsy values
const truthyOnly = Object.fromEntries(
Object.entries(product).filter(([, v]) => Boolean(v))
);
// Check if a key has a specific value
const priceAbove5 = Object.entries(product)
.filter(([key, val]) => typeof val === 'number' && val > 5)
.map(([key]) => key);
// ["price", "stock"]
Object.assign and Spread
// Object.assign — copy properties to a target object
const target = { a: 1 };
const source = { b: 2, c: 3 };
Object.assign(target, source); // target is now { a: 1, b: 2, c: 3 }
// Shallow clone
const clone = Object.assign({}, product);
// Merge with override
const merged = Object.assign({}, defaults, userSettings);
// Spread is preferred for most cases (cleaner, same shallow copy)
const clone2 = { ...product };
const merged2 = { ...defaults, ...userSettings };
Object.freeze and Object.seal
const config = Object.freeze({
apiUrl: "https://api.example.com",
timeout: 5000
});
config.timeout = 10000; // silently fails (throws in strict mode)
config.timeout; // still 5000
// Only freezes shallow — nested objects can still be mutated
const state = Object.freeze({ user: { name: "Alice" } });
state.user.name = "Bob"; // works! user object isn't frozen
state.user = {}; // fails — top-level is frozen
// Deep freeze
function deepFreeze(obj) {
Object.getOwnPropertyNames(obj).forEach(name => {
const value = obj[name];
if (typeof value === "object" && value !== null) {
deepFreeze(value);
}
});
return Object.freeze(obj);
}
hasOwn and in Operator
const user = { name: "Alice", age: 30 };
// Check if property exists
"name" in user; // true
"email" in user; // false
"toString" in user; // true — inherited from Object.prototype!
// Object.hasOwn — only own properties (ES2022, preferred)
Object.hasOwn(user, "name"); // true
Object.hasOwn(user, "toString"); // false — inherited, not own
// Old way — same effect
user.hasOwnProperty("name"); // true
Object.create and Prototypes
// Create object with specific prototype
const animal = {
speak() {
return `${this.name} makes a sound.`;
}
};
const dog = Object.create(animal);
dog.name = "Rex";
dog.speak(); // "Rex makes a sound."
// Object.getPrototypeOf — inspect the prototype chain
Object.getPrototypeOf(dog) === animal; // true
Object.getPrototypeOf(animal) === Object.prototype; // true
Object.getPrototypeOf(Object.prototype); // null (end of chain)
Computed Property Names
const field = "email";
const user = {
name: "Alice",
[field]: "alice@example.com", // computed key
[`get${field.charAt(0).toUpperCase() + field.slice(1)}`]: function() { // dynamic method name
return this[field];
}
};
// Very useful for dynamic objects from form data
function formToObject(formElement) {
return [...formElement.elements].reduce((obj, el) => {
if (el.name) obj[el.name] = el.value;
return obj;
}, {});
}
Property Descriptors
// defineProperty — control how properties behave
const obj = {};
Object.defineProperty(obj, "readOnly", {
value: 42,
writable: false, // can't change the value
enumerable: true, // shows up in for...in and Object.keys
configurable: false // can't delete or redefine
});
obj.readOnly = 100; // fails silently (throws in strict mode)
obj.readOnly; // 42
// getters and setters via defineProperty
const user = { _name: "Alice" };
Object.defineProperty(user, "name", {
get() { return this._name.toUpperCase(); },
set(value) { this._name = value.trim(); },
enumerable: true
});
user.name = " bob ";
user.name; // "BOB"
// shorthand in object literal (usually preferred)
const person = {
_age: 0,
get age() { return this._age; },
set age(val) {
if (val < 0) throw new Error("Age can't be negative");
this._age = val;
}
};
Practical Utility Functions
// Pick specific keys from an object
function pick(obj, keys) {
return Object.fromEntries(
keys.filter(k => k in obj).map(k => [k, obj[k]])
);
}
pick(user, ["name", "email"]);
// Omit specific keys
function omit(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([k]) => !keys.includes(k))
);
}
omit(user, ["password", "token"]);
// Deep equality check
function deepEqual(a, b) {
if (a === b) return true;
if (typeof a !== 'object' || typeof b !== 'object') return false;
if (a === null || b === null) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
return keysA.every(key => deepEqual(a[key], b[key]));
}
Next lesson: JSON — parsing, serializing, and working with JSON in JavaScript applications.
📱
Get Notes Free →Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises