Back to Blog
JavaScriptObjectsMethodsES6

JavaScript Object Methods Guide

Master JavaScript Object methods for manipulation, iteration, and transformation.

B
Bootspring Team
Engineering
November 8, 2018
7 min read

JavaScript provides powerful Object methods for working with objects. Here's a comprehensive guide.

Object.keys(), values(), entries()#

1const user = { 2 name: 'John', 3 age: 30, 4 email: 'john@example.com' 5}; 6 7// Get keys 8const keys = Object.keys(user); 9// ['name', 'age', 'email'] 10 11// Get values 12const values = Object.values(user); 13// ['John', 30, 'john@example.com'] 14 15// Get entries (key-value pairs) 16const entries = Object.entries(user); 17// [['name', 'John'], ['age', 30], ['email', 'john@example.com']] 18 19// Iterate over object 20for (const [key, value] of Object.entries(user)) { 21 console.log(`${key}: ${value}`); 22} 23 24// Transform object 25const doubled = Object.fromEntries( 26 Object.entries(user).map(([key, value]) => [ 27 key, 28 typeof value === 'number' ? value * 2 : value 29 ]) 30);

Object.assign()#

1// Merge objects 2const defaults = { theme: 'light', lang: 'en' }; 3const userPrefs = { theme: 'dark' }; 4 5const config = Object.assign({}, defaults, userPrefs); 6// { theme: 'dark', lang: 'en' } 7 8// Clone object (shallow) 9const original = { a: 1, b: { c: 2 } }; 10const clone = Object.assign({}, original); 11 12// Note: nested objects are still referenced 13clone.b.c = 3; 14console.log(original.b.c); // 3 15 16// Multiple sources 17const merged = Object.assign( 18 {}, 19 { a: 1 }, 20 { b: 2 }, 21 { a: 3, c: 4 } 22); 23// { a: 3, b: 2, c: 4 } - later values override 24 25// Mutate target 26const target = { a: 1 }; 27Object.assign(target, { b: 2 }); 28// target is now { a: 1, b: 2 }

Object.fromEntries()#

1// Convert entries to object 2const entries = [ 3 ['name', 'John'], 4 ['age', 30] 5]; 6 7const obj = Object.fromEntries(entries); 8// { name: 'John', age: 30 } 9 10// From Map 11const map = new Map([ 12 ['a', 1], 13 ['b', 2] 14]); 15 16const fromMap = Object.fromEntries(map); 17// { a: 1, b: 2 } 18 19// Transform object 20const original = { a: 1, b: 2, c: 3 }; 21 22const transformed = Object.fromEntries( 23 Object.entries(original) 24 .filter(([key]) => key !== 'b') 25 .map(([key, value]) => [key.toUpperCase(), value * 10]) 26); 27// { A: 10, C: 30 } 28 29// Query string to object 30const queryString = 'name=John&age=30&city=NYC'; 31const params = Object.fromEntries( 32 new URLSearchParams(queryString) 33); 34// { name: 'John', age: '30', city: 'NYC' }

Object.freeze() and Object.seal()#

1// Freeze - no changes allowed 2const frozen = Object.freeze({ 3 name: 'John', 4 details: { age: 30 } 5}); 6 7frozen.name = 'Jane'; // Silently fails (or throws in strict mode) 8frozen.email = 'test'; // Silently fails 9delete frozen.name; // Silently fails 10 11// Note: Nested objects are NOT frozen 12frozen.details.age = 31; // Works! 13 14// Deep freeze 15function deepFreeze(obj) { 16 Object.keys(obj).forEach(key => { 17 if (typeof obj[key] === 'object' && obj[key] !== null) { 18 deepFreeze(obj[key]); 19 } 20 }); 21 return Object.freeze(obj); 22} 23 24// Seal - can modify existing, can't add/remove 25const sealed = Object.seal({ name: 'John', age: 30 }); 26 27sealed.name = 'Jane'; // Works 28sealed.email = 'test'; // Fails 29delete sealed.name; // Fails 30 31// Check status 32Object.isFrozen(frozen); // true 33Object.isSealed(sealed); // true

Object.defineProperty()#

1const obj = {}; 2 3// Define property with descriptors 4Object.defineProperty(obj, 'name', { 5 value: 'John', 6 writable: true, // Can be changed 7 enumerable: true, // Shows in for...in 8 configurable: true // Can be deleted/modified 9}); 10 11// Read-only property 12Object.defineProperty(obj, 'id', { 13 value: 123, 14 writable: false, 15 enumerable: true, 16 configurable: false 17}); 18 19obj.id = 456; // Fails silently (or throws in strict) 20 21// Getter and setter 22Object.defineProperty(obj, 'fullName', { 23 get() { 24 return `${this.firstName} ${this.lastName}`; 25 }, 26 set(value) { 27 const [first, last] = value.split(' '); 28 this.firstName = first; 29 this.lastName = last; 30 }, 31 enumerable: true 32}); 33 34// Define multiple properties 35Object.defineProperties(obj, { 36 firstName: { value: 'John', writable: true, enumerable: true }, 37 lastName: { value: 'Doe', writable: true, enumerable: true } 38});

Object.getOwnPropertyDescriptor()#

1const obj = { 2 name: 'John', 3 get fullName() { 4 return this.name; 5 } 6}; 7 8// Get single descriptor 9const desc = Object.getOwnPropertyDescriptor(obj, 'name'); 10// { value: 'John', writable: true, enumerable: true, configurable: true } 11 12// Get getter descriptor 13const getterDesc = Object.getOwnPropertyDescriptor(obj, 'fullName'); 14// { get: [Function], set: undefined, enumerable: true, configurable: true } 15 16// Get all descriptors 17const allDesc = Object.getOwnPropertyDescriptors(obj); 18 19// Clone with descriptors preserved 20const clone = Object.defineProperties( 21 {}, 22 Object.getOwnPropertyDescriptors(obj) 23);

Object.create()#

1// Create with prototype 2const personProto = { 3 greet() { 4 return `Hello, ${this.name}`; 5 } 6}; 7 8const person = Object.create(personProto); 9person.name = 'John'; 10person.greet(); // 'Hello, John' 11 12// With property descriptors 13const user = Object.create(personProto, { 14 name: { 15 value: 'John', 16 writable: true, 17 enumerable: true 18 }, 19 age: { 20 value: 30, 21 writable: false 22 } 23}); 24 25// Create null prototype object 26const dict = Object.create(null); 27dict.hasOwnProperty; // undefined - no inherited methods 28dict['key'] = 'value'; 29 30// Useful for dictionary-like objects 31function createDict() { 32 return Object.create(null); 33}

Object.getPrototypeOf() and setPrototypeOf()#

1const animal = { 2 speak() { 3 console.log('Animal speaks'); 4 } 5}; 6 7const dog = { 8 bark() { 9 console.log('Woof!'); 10 } 11}; 12 13// Get prototype 14const proto = Object.getPrototypeOf(dog); 15// Object.prototype 16 17// Set prototype (not recommended for performance) 18Object.setPrototypeOf(dog, animal); 19 20dog.speak(); // 'Animal speaks' 21dog.bark(); // 'Woof!' 22 23// Check prototype chain 24Object.getPrototypeOf(dog) === animal; // true

Object.is()#

1// Stricter equality than === 2Object.is(25, 25); // true 3Object.is('foo', 'foo'); // true 4Object.is(null, null); // true 5 6// Handles special cases differently than === 7Object.is(NaN, NaN); // true (=== returns false) 8Object.is(0, -0); // false (=== returns true) 9 10// Same as === for most cases 11Object.is([], []); // false (different references) 12 13// Useful for comparing values 14function equals(a, b) { 15 return Object.is(a, b); 16}

Object.hasOwn()#

1// Modern replacement for hasOwnProperty 2const obj = { name: 'John' }; 3 4Object.hasOwn(obj, 'name'); // true 5Object.hasOwn(obj, 'toString'); // false (inherited) 6 7// Works with null prototype objects 8const dict = Object.create(null); 9dict.key = 'value'; 10 11// Old way fails on null prototype 12// dict.hasOwnProperty('key'); // Error! 13 14// New way works 15Object.hasOwn(dict, 'key'); // true 16 17// Safer than in operator 18'name' in obj; // true 19'toString' in obj; // true (checks prototype chain) 20Object.hasOwn(obj, 'toString'); // false

Object.groupBy() (ES2024)#

1const items = [ 2 { name: 'Apple', type: 'fruit' }, 3 { name: 'Carrot', type: 'vegetable' }, 4 { name: 'Banana', type: 'fruit' }, 5 { name: 'Broccoli', type: 'vegetable' } 6]; 7 8// Group by property 9const grouped = Object.groupBy(items, item => item.type); 10// { 11// fruit: [{ name: 'Apple', ... }, { name: 'Banana', ... }], 12// vegetable: [{ name: 'Carrot', ... }, { name: 'Broccoli', ... }] 13// } 14 15// Group numbers 16const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 17const byParity = Object.groupBy(numbers, n => 18 n % 2 === 0 ? 'even' : 'odd' 19); 20// { odd: [1, 3, 5, 7, 9], even: [2, 4, 6, 8] }

Iteration Patterns#

1const obj = { a: 1, b: 2, c: 3 }; 2 3// for...in (includes inherited, use hasOwn to filter) 4for (const key in obj) { 5 if (Object.hasOwn(obj, key)) { 6 console.log(key, obj[key]); 7 } 8} 9 10// Object.keys + forEach 11Object.keys(obj).forEach(key => { 12 console.log(key, obj[key]); 13}); 14 15// Object.entries + destructuring 16for (const [key, value] of Object.entries(obj)) { 17 console.log(key, value); 18} 19 20// Reduce to transform 21const doubled = Object.entries(obj).reduce( 22 (acc, [key, value]) => ({ ...acc, [key]: value * 2 }), 23 {} 24);

Best Practices#

Common Methods: ✓ Object.keys/values/entries for iteration ✓ Object.assign for merging ✓ Object.fromEntries for transformation ✓ Object.hasOwn for property checks Immutability: ✓ Object.freeze for constants ✓ Spread for shallow copies ✓ Deep clone for nested objects ✓ Consider libraries for complex cases Descriptors: ✓ defineProperty for advanced control ✓ getOwnPropertyDescriptors for cloning ✓ Use for computed properties ✓ Understand enumerable/configurable Avoid: ✗ Mutating frozen objects ✗ setPrototypeOf in hot paths ✗ hasOwnProperty on null prototype ✗ Confusing === with Object.is

Conclusion#

JavaScript Object methods provide powerful tools for manipulating objects. Use Object.keys/values/entries for iteration, Object.assign or spread for merging, and Object.fromEntries for transformation. For advanced use cases, Object.defineProperty and descriptors offer fine-grained control. Always consider whether you need shallow or deep operations.

Share this article

Help spread the word about Bootspring