Object Methods (Object.keys, entries, assign, etc.)
JavaScript provides many built-in methods for working with objects efficiently.
Object.keys()
javascriptconst person = { name: "Alice", age: 30, city: "New York", occupation: "Developer" }; // Get array of property names const keys = Object.keys(person); console.log(keys); // ["name", "age", "city", "occupation"] // Iterate over keys Object.keys(person).forEach(key => { console.log(`${key}: ${person[key]}`); }); // Filter properties const stringProperties = Object.keys(person).filter(key => typeof person[key] === 'string' ); console.log(stringProperties); // ["name", "city", "occupation"]
Object.values()
javascriptconst scores = { math: 95, science: 87, english: 92, history: 88 }; // Get array of values const values = Object.values(scores); console.log(values); // [95, 87, 92, 88] // Calculate average const average = Object.values(scores).reduce((sum, score) => sum + score, 0) / Object.values(scores).length; console.log(average); // 90.5 // Find maximum score const maxScore = Math.max(...Object.values(scores)); console.log(maxScore); // 95
Object.entries()
javascriptconst product = { name: "Laptop", price: 999, brand: "Dell", inStock: true }; // Get array of [key, value] pairs const entries = Object.entries(product); console.log(entries); // [["name", "Laptop"], ["price", 999], ["brand", "Dell"], ["inStock", true]] // Convert to Map const productMap = new Map(Object.entries(product)); // Filter entries const stringEntries = Object.entries(product).filter(([key, value]) => typeof value === 'string' ); console.log(stringEntries); // [["name", "Laptop"], ["brand", "Dell"]] // Transform object const upperCaseProduct = Object.fromEntries( Object.entries(product).map(([key, value]) => [ key.toUpperCase(), typeof value === 'string' ? value.toUpperCase() : value ]) );
Object.assign()
javascript// Copy properties from source to target const target = { a: 1, b: 2 }; const source = { b: 3, c: 4 }; const result = Object.assign(target, source); console.log(result); // { a: 1, b: 3, c: 4 } console.log(target); // { a: 1, b: 3, c: 4 } - target is modified! // Create new object (don't modify target) const original = { a: 1, b: 2 }; const extension = { c: 3, d: 4 }; const combined = Object.assign({}, original, extension); console.log(combined); // { a: 1, b: 2, c: 3, d: 4 } console.log(original); // { a: 1, b: 2 } - unchanged // Multiple sources const defaults = { theme: "light", lang: "en" }; const userPrefs = { theme: "dark" }; const sessionPrefs = { fontSize: "large" }; const finalPrefs = Object.assign({}, defaults, userPrefs, sessionPrefs); console.log(finalPrefs); // { theme: "dark", lang: "en", fontSize: "large" }
Object.fromEntries()
javascript// Convert entries back to object const entries = [["name", "Alice"], ["age", 30], ["city", "Boston"]]; const person = Object.fromEntries(entries); console.log(person); // { name: "Alice", age: 30, city: "Boston" } // Transform object properties const prices = { laptop: 999, phone: 599, tablet: 399 }; // Apply discount const discountedPrices = Object.fromEntries( Object.entries(prices).map(([item, price]) => [item, price * 0.9]) ); console.log(discountedPrices); // { laptop: 899.1, phone: 539.1, tablet: 359.1 } // Filter and transform const users = { alice: { age: 25, active: true }, bob: { age: 30, active: false }, charlie: { age: 35, active: true } }; const activeUsers = Object.fromEntries( Object.entries(users).filter(([name, user]) => user.active) ); console.log(activeUsers); // { alice: { age: 25, active: true }, charlie: { age: 35, active: true } }
Object.hasOwnProperty() and Object.hasOwn()
javascriptconst person = { name: "Alice", age: 30 }; // Check if object has own property (not inherited) console.log(person.hasOwnProperty('name')); // true console.log(person.hasOwnProperty('toString')); // false (inherited) // Modern alternative (ES2022) console.log(Object.hasOwn(person, 'name')); // true console.log(Object.hasOwn(person, 'toString')); // false // Safe property checking function safeGet(obj, prop) { return Object.hasOwn(obj, prop) ? obj[prop] : undefined; } // Iterate only own properties for (let key in person) { if (Object.hasOwn(person, key)) { console.log(`${key}: ${person[key]}`); } }
Object.getOwnPropertyNames()
javascriptconst obj = { visible: "I'm enumerable", [Symbol('hidden')]: "I'm a symbol" }; // Define non-enumerable property Object.defineProperty(obj, 'hidden', { value: "I'm not enumerable", enumerable: false }); console.log(Object.keys(obj)); // ["visible"] - only enumerable console.log(Object.getOwnPropertyNames(obj)); // ["visible", "hidden"] - all string properties
Object.freeze(), Object.seal(), Object.preventExtensions()
javascriptconst user = { name: "Alice", age: 30 }; // Object.freeze() - completely immutable const frozenUser = Object.freeze({ ...user }); frozenUser.name = "Bob"; // Ignored in non-strict mode, error in strict mode frozenUser.city = "NYC"; // Ignored delete frozenUser.age; // Ignored console.log(Object.isFrozen(frozenUser)); // true // Object.seal() - can modify existing properties, can't add/delete const sealedUser = Object.seal({ ...user }); sealedUser.name = "Charlie"; // Works sealedUser.city = "Boston"; // Ignored delete sealedUser.age; // Ignored console.log(Object.isSealed(sealedUser)); // true // Object.preventExtensions() - can't add new properties const extensibleUser = Object.preventExtensions({ ...user }); extensibleUser.name = "Diana"; // Works extensibleUser.city = "LA"; // Ignored delete extensibleUser.age; // Works console.log(Object.isExtensible(extensibleUser)); // false
Practical Examples
javascript// Configuration merger function mergeConfig(defaults, userConfig) { return Object.assign({}, defaults, userConfig); } const defaultConfig = { theme: "light", language: "en", notifications: true, autoSave: false }; const userConfig = { theme: "dark", autoSave: true }; const finalConfig = mergeConfig(defaultConfig, userConfig); console.log(finalConfig); // Object transformation utilities const objectUtils = { // Pick specific properties pick(obj, keys) { return Object.fromEntries( keys.filter(key => key in obj).map(key => [key, obj[key]]) ); }, // Omit specific properties omit(obj, keys) { return Object.fromEntries( Object.entries(obj).filter(([key]) => !keys.includes(key)) ); }, // Map over object values mapValues(obj, fn) { return Object.fromEntries( Object.entries(obj).map(([key, value]) => [key, fn(value, key)]) ); }, // Filter object by predicate filter(obj, predicate) { return Object.fromEntries( Object.entries(obj).filter(([key, value]) => predicate(value, key)) ); }, // Deep merge objects deepMerge(target, source) { const result = { ...target }; for (let key in source) { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { result[key] = this.deepMerge(result[key] || {}, source[key]); } else { result[key] = source[key]; } } return result; } }; // Usage examples const user = { id: 1, name: "Alice", email: "alice@example.com", password: "secret123", age: 30, isActive: true }; const publicUser = objectUtils.pick(user, ['id', 'name', 'email']); console.log(publicUser); // { id: 1, name: "Alice", email: "alice@example.com" } const userWithoutPassword = objectUtils.omit(user, ['password']); console.log(userWithoutPassword); // All properties except password const uppercaseUser = objectUtils.mapValues(user, (value) => typeof value === 'string' ? value.toUpperCase() : value ); const activeUsers = objectUtils.filter({ user1: user, user2: { ...user, isActive: false } }, (user) => user.isActive ); // Form data processing function processFormData(formData) { // Convert FormData or form object to clean object const cleanData = Object.fromEntries( Object.entries(formData) .filter(([key, value]) => value !== '' && value != null) .map(([key, value]) => [key, typeof value === 'string' ? value.trim() : value]) ); return cleanData; } // API response transformation function transformApiResponse(response) { return Object.fromEntries( Object.entries(response) .map(([key, value]) => [ key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()), // snake_case to camelCase value ]) ); } // Example: snake_case to camelCase const apiData = { user_id: 123, first_name: "John", last_name: "Doe", email_address: "john@example.com" }; const camelCaseData = transformApiResponse(apiData); console.log(camelCaseData); // { userId: 123, firstName: "John", lastName: "Doe", emailAddress: "john@example.com" } // Object validation function validateObject(obj, schema) { const errors = []; Object.entries(schema).forEach(([key, rules]) => { const value = obj[key]; if (rules.required && (value === undefined || value === null || value === '')) { errors.push(`${key} is required`); return; } if (value !== undefined && rules.type && typeof value !== rules.type) { errors.push(`${key} must be of type ${rules.type}`); } if (rules.minLength && typeof value === 'string' && value.length < rules.minLength) { errors.push(`${key} must be at least ${rules.minLength} characters`); } }); return { isValid: errors.length === 0, errors }; } // Usage const userData = { name: "Alice", email: "alice@example.com", age: 25 }; const userSchema = { name: { required: true, type: 'string', minLength: 2 }, email: { required: true, type: 'string' }, age: { required: true, type: 'number' } }; const validation = validateObject(userData, userSchema); console.log(validation); // { isValid: true, errors: [] }
Performance Tips
javascript// Cache Object.keys() results when iterating multiple times const largeObject = { /* many properties */ }; const keys = Object.keys(largeObject); // Cache this // Use Object.hasOwn() instead of hasOwnProperty() for better performance // and to avoid prototype pollution issues if (Object.hasOwn(obj, 'property')) { // Safe property access } // For frequent property checks, consider using Map instead of Object const frequentLookups = new Map([ ['key1', 'value1'], ['key2', 'value2'] ]); // Use Object.assign() for shallow copying small objects // Use spread operator for better readability const copy = { ...original }; // Preferred over Object.assign({}, original)
Common Patterns
javascript// Group array of objects by property function groupBy(array, key) { return array.reduce((groups, item) => { const group = item[key]; groups[group] = groups[group] || []; groups[group].push(item); return groups; }, {}); } // Count occurrences function countBy(array, key) { return array.reduce((counts, item) => { const value = item[key]; counts[value] = (counts[value] || 0) + 1; return counts; }, {}); } // Index array by property function indexBy(array, key) { return Object.fromEntries( array.map(item => [item[key], item]) ); } // Usage const users = [ { id: 1, name: "Alice", department: "Engineering" }, { id: 2, name: "Bob", department: "Marketing" }, { id: 3, name: "Charlie", department: "Engineering" } ]; const byDepartment = groupBy(users, 'department'); const departmentCounts = countBy(users, 'department'); const usersById = indexBy(users, 'id');