Object Methods and Property Handling
Understanding Object.keys, entries, assign, and other essential object methods
Challenge
Section titled “Challenge”You need to work with complex nested objects: merging configurations, extracting specific properties, and transforming object structures. How do you do this efficiently?
Explanation
Section titled “Explanation”JavaScript provides powerful Object methods for property introspection and manipulation. These are essential for working with data structures in modern JavaScript applications.
Object.keys, values, entries
Section titled “Object.keys, values, entries”const user = { name: 'Alice', email: 'alice@example.com', age: 30, active: true};
// Get property namesconsole.log(Object.keys(user));// ['name', 'email', 'age', 'active']
// Get property valuesconsole.log(Object.values(user));// ['Alice', 'alice@example.com', 30, true]
// Get [key, value] pairsconsole.log(Object.entries(user));// [// ['name', 'Alice'],// ['email', 'alice@example.com'],// ['age', 30],// ['active', true]// ]
// Iterate efficientlyfor (const [key, value] of Object.entries(user)) { console.log(`${key}: ${value}`);}Object.assign and Merging
Section titled “Object.assign and Merging”// Merge objects (shallow copy)const defaults = { theme: 'light', language: 'en', timezone: 'UTC'};
const userSettings = { theme: 'dark', fontSize: 14};
const merged = Object.assign({}, defaults, userSettings);console.log(merged);// {// theme: 'dark', // Overridden// language: 'en', // From defaults// timezone: 'UTC', // From defaults// fontSize: 14 // From userSettings// }
// Mutate original (not recommended)Object.assign(defaults, userSettings);
// Merge multiple objectsconst result = Object.assign( {}, { a: 1, b: 2 }, { b: 3, c: 4 }, { c: 5, d: 6 });// { a: 1, b: 3, c: 5, d: 6 }Solution: Object Transformation
Section titled “Solution: Object Transformation”// Transform API response to application modelconst apiResponse = { user_id: 1, first_name: 'John', last_name: 'Doe', email_address: 'john@example.com', created_at: '2024-01-15', metadata: { role: 'admin', department: 'Engineering' }};
// ✅ Transform using entriesconst transformed = Object.fromEntries( Object.entries(apiResponse) .map(([key, value]) => [ key.replace(/_([a-z])/g, (_, char) => char.toUpperCase()), value ]));
// Result: camelCase keys// {// userId: 1,// firstName: 'John',// lastName: 'Doe',// emailAddress: 'john@example.com',// ...// }
// ✅ Selective transformationconst userData = Object.fromEntries( Object.entries(apiResponse) .filter(([key]) => !key.startsWith('_') && key !== 'metadata') .map(([key, value]) => [ key.replace(/_/g, ''), value ]));Object.create and Prototype
Section titled “Object.create and Prototype”// Create object with specific prototypeconst proto = { greet() { return `Hello, ${this.name}`; }};
const obj = Object.create(proto);obj.name = 'Alice';console.log(obj.greet()); // Hello, Alice
// Create object with no prototypeconst plain = Object.create(null);// No Object.prototype methods available
// Clone with same prototypeconst original = { name: 'Bob' };const copy = Object.create(Object.getPrototypeOf(original));Object.assign(copy, original);Property Descriptors
Section titled “Property Descriptors”const obj = {};
// Define property with descriptorsObject.defineProperty(obj, 'name', { value: 'Alice', writable: false, // Cannot be modified enumerable: true, // Shows in for...in configurable: false // Cannot be reconfigured});
obj.name = 'Bob'; // No error but value unchanged
// Define multiple propertiesObject.defineProperties(obj, { age: { value: 30, writable: true, enumerable: true }, email: { value: 'alice@example.com', enumerable: false // Hidden from iteration }});
// Get descriptorconsole.log(Object.getOwnPropertyDescriptor(obj, 'name'));// { value: 'Alice', writable: false, enumerable: true, configurable: false }
// Get all descriptorsconsole.log(Object.getOwnPropertyDescriptors(obj));Sealing and Freezing
Section titled “Sealing and Freezing”// Freeze: Can't add/remove/modify propertiesconst frozen = Object.freeze({ x: 1, y: 2 });frozen.x = 99; // Error in strict mode, silent fail otherwisefrozen.z = 3; // Error in strict modedelete frozen.x; // Error in strict mode
// Seal: Can't add/remove properties but can modifyconst sealed = Object.seal({ a: 1, b: 2 });sealed.a = 99; // OKsealed.c = 3; // Error in strict mode
// Check stateconsole.log(Object.isFrozen(frozen)); // trueconsole.log(Object.isSealed(sealed)); // truePractical Example: Configuration Merge
Section titled “Practical Example: Configuration Merge”function mergeConfigs(...configs) { return configs.reduce((merged, config) => { // Deep merge for nested objects for (const [key, value] of Object.entries(config)) { if ( value !== null && typeof value === 'object' && !Array.isArray(value) && merged[key] !== null && typeof merged[key] === 'object' && !Array.isArray(merged[key]) ) { merged[key] = mergeConfigs(merged[key], value); } else { merged[key] = value; } } return merged; }, {});}
const base = { database: { host: 'localhost', port: 5432, credentials: { user: 'admin' } }, cache: { enabled: true }};
const override = { database: { host: 'prod.example.com', credentials: { password: 'secret' } }};
const merged = mergeConfigs(base, override);// {// database: {// host: 'prod.example.com',// port: 5432,// credentials: { user: 'admin', password: 'secret' }// },// cache: { enabled: true }// }