JavaScript 46 🧬 Object methods in depth
const obj = { a: 1, b: 2, c: 3 };
Object.keys(obj);
Object.values(obj);
Object.entries(obj);
Object.fromEntries([['a', 1], ['b', 2]]);
Object.assign({}, obj, { d: 4 });
Object.freeze(obj);
Object.seal(obj);
Object.isFrozen(obj);
Object.isSealed(obj);
Object.hasOwn(obj, 'a');
Object.create(null);
Object.defineProperty(obj, 'x', { value: 42 });
Object.getOwnPropertyDescriptor(obj, 'a');
Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, null);
Object.is(1, 1);
Object.is(NaN, NaN);
Object.groupBy([1, 2, 3, 4], n => n % 2 === 0 ? 'even' : 'odd');
The Object global is a toolbox — it’s the constructor for objects, but it also holds static methods that work on any object. These methods are how you enumerate, copy, freeze, compare, and inspect objects. They’re the foundation of modern JavaScript patterns like immutability and destructuring.
Key point: Most Object.* methods work on own enumerable properties by default. Some methods work on prototypes, symbols, or descriptors. Knowing which is which prevents surprises when objects have inherited properties.
a – Enumerating object properties
These methods give you arrays of keys, values, or key-value pairs.
Object.keys() — array of keys:
const user = { name: 'Alice', age: 30 };
console.log(Object.keys(user));
// [ [ 'name', 'age' ] ]
Only own enumerable properties, in insertion order.
Object.values() — array of values:
console.log(Object.values(user));
// [ [ 'Alice', 30 ] ]
Object.entries() — array of [key, value] pairs:
console.log(Object.entries(user));
// [ [ [ 'name', 'Alice' ], [ 'age', 30 ] ] ]
Object.fromEntries() — the reverse:
const entries = [['name', 'Alice'], ['age', 30]];
const user = Object.fromEntries(entries);
console.log(user);
// [ { name: 'Alice', age: 30 } ]
Converting Map to Object:
const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map);
console.log(obj);
// [ { a: 1, b: 2 } ]
Converting Object to Map:
const obj = { a: 1, b: 2 };
const map = new Map(Object.entries(obj));
console.log(map);
// [ Map(2) { 'a' => 1, 'b' => 2 } ]
Iterating with Object.entries():
const prices = { apple: 1.5, banana: 0.75 };
for (const [fruit, price] of Object.entries(prices)) {
console.log(`${fruit}: $${price}`);
}
// [ apple: $1.5 ]
// [ banana: $0.75 ]
Transforming values:
const prices = { apple: 1.5, banana: 0.75 };
const doubled = Object.fromEntries(
Object.entries(prices).map(([k, v]) => [k, v * 2])
);
console.log(doubled);
// [ { apple: 3, banana: 1.5 } ]
Filtering:
const mixed = { a: 1, b: null, c: 3, d: undefined };
const clean = Object.fromEntries(
Object.entries(mixed).filter(([_, v]) => v != null)
);
console.log(clean);
// [ { a: 1, c: 3 } ]
Comparison:
| Method | Returns |
|---|---|
Object.keys(obj) | Array of keys |
Object.values(obj) | Array of values |
Object.entries(obj) | Array of [key, value] |
Object.fromEntries(arr) | Object from pairs |
Property order:
| Key type | Order |
|---|---|
| Integer-like | Numeric ascending |
| String | Insertion order |
| Symbol | Insertion order |
const obj = { b: 1, 2: 'two', a: 3, 1: 'one' };
console.log(Object.keys(obj));
// [ [ '1', '2', 'b', 'a' ] ]
b – Copying, merging, and comparing
Object.assign() — copy and merge:
const target = { a: 1 };
const source = { b: 2, c: 3 };
Object.assign(target, source);
console.log(target);
// [ { a: 1, b: 2, c: 3 } ]
The target is mutated. To create a new object, use an empty target:
const merged = Object.assign({}, { a: 1 }, { b: 2 });
console.log(merged);
// [ { a: 1, b: 2 } ]
Later sources override earlier ones:
Object.assign({}, { a: 1, b: 2 }, { b: 3 });
// [ { a: 1, b: 3 } ]
Object.assign is shallow:
const original = { a: { x: 1 } };
const copy = Object.assign({}, original);
copy.a.x = 99;
console.log(original.a.x);
// [ 99 ] ← shared
Spread vs Object.assign:
// These are equivalent
const merged1 = Object.assign({}, a, b);
const merged2 = { ...a, ...b };
Spread is preferred in modern code.
Object.is() — strict equality with edge cases:
console.log(Object.is(1, 1));
// [ true ]
console.log(Object.is('a', 'a'));
// [ true ]
console.log(Object.is({}, {}));
// [ false ]
Object.is differs from === in two cases:
console.log(NaN === NaN);
// [ false ]
console.log(Object.is(NaN, NaN));
// [ true ]
console.log(+0 === -0);
// [ true ]
console.log(Object.is(+0, -0));
// [ false ]
| Case | === | Object.is |
|---|---|---|
NaN === NaN | false | true |
+0 === -0 | true | false |
| Normal values | Same | Same |
Use Object.is when you need exact identity, especially with NaN or signed zeros.
Shallow vs deep copy:
// Shallow — spread or assign
const shallow = { ...original };
// Deep — structuredClone
const deep = structuredClone(original);
structuredClone handles nested objects, arrays, Maps, Sets, Dates — but not functions or class instances.
Comparing objects:
const a = { x: 1 };
const b = { x: 1 };
console.log(a === b);
// [ false ] ← different references
console.log(JSON.stringify(a) === JSON.stringify(b));
// [ true ] ← same shape and values
console.log(Object.is(a, b));
// [ false ]
Objects compare by reference, not by structure.
c – Freezing and sealing
These methods control whether an object can be modified.
Object.freeze() — fully immutable:
const config = Object.freeze({ host: 'localhost', port: 8080 });
config.port = 9090;
console.log(config.port);
// [ 8080 ] ← unchanged
config.newKey = 'x';
console.log(config.newKey);
// [ undefined ]
delete config.host;
console.log(config.host);
// [ 'localhost' ] ← still there
You can’t add, modify, or delete properties on a frozen object. In strict mode, these operations throw:
'use strict';
const obj = Object.freeze({ a: 1 });
obj.a = 2; // TypeError: Cannot assign to read only property
Object.seal() — no add/delete, but modify allowed:
const user = Object.seal({ name: 'Alice', age: 30 });
user.age = 31; // ✅ works
user.newKey = 'x'; // ❌ ignored
delete user.name; // ❌ ignored
Existing properties can be changed; new ones can’t be added or removed.
Object.preventExtensions() — no new properties:
const obj = Object.preventExtensions({ a: 1 });
obj.a = 2; // ✅ works
obj.b = 3; // ❌ ignored
delete obj.a; // ✅ works
Comparison:
| Method | Add | Modify | Delete |
|---|---|---|---|
Object.freeze | ❌ | ❌ | ❌ |
Object.seal | ❌ | ✅ | ❌ |
Object.preventExtensions | ❌ | ✅ | ✅ |
| (default) | ✅ | ✅ | ✅ |
Checking:
const frozen = Object.freeze({ a: 1 });
const sealed = Object.seal({ a: 1 });
const prevented = Object.preventExtensions({ a: 1 });
console.log(Object.isFrozen(frozen));
// [ true ]
console.log(Object.isSealed(sealed));
// [ true ]
console.log(Object.isExtensible(prevented));
// [ false ]
Freeze is shallow:
const obj = Object.freeze({ a: { b: 1 } });
obj.a.b = 99; // ✅ still works — inner object not frozen
console.log(obj.a.b);
// [ 99 ]
To freeze deeply, recurse:
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach(v => {
if (v && typeof v === 'object') deepFreeze(v);
});
return obj;
}
d – Property descriptors and creation
Object.defineProperty() — precise property control:
const obj = {};
Object.defineProperty(obj, 'x', {
value: 42,
writable: false,
enumerable: false,
configurable: false
});
console.log(obj.x);
// [ 42 ]
obj.x = 99;
console.log(obj.x);
// [ 42 ] ← unchanged (writable: false)
Descriptor flags:
| Flag | Meaning |
|---|---|
value | The value |
writable | Can be changed |
enumerable | Shows in for...in, Object.keys |
configurable | Can be deleted or redefined |
get | Getter function |
set | Setter function |
Object.defineProperties() — multiple properties:
const obj = {};
Object.defineProperties(obj, {
name: { value: 'Alice', enumerable: true },
age: { value: 30, enumerable: true }
});
console.log(obj);
// [ { name: 'Alice', age: 30 } ]
Object.getOwnPropertyDescriptor() — inspect a descriptor:
const obj = { a: 1 };
const desc = Object.getOwnPropertyDescriptor(obj, 'a');
console.log(desc);
// [ { value: 1, writable: true, enumerable: true, configurable: true } ]
Object.getOwnPropertyDescriptors() — all descriptors:
const obj = { a: 1, b: 2 };
console.log(Object.getOwnPropertyDescriptors(obj));
// [ { a: {...}, b: {...} } ]
Getters and setters with defineProperty:
const obj = {
_value: 0
};
Object.defineProperty(obj, 'value', {
get() { return this._value; },
set(v) { this._value = v * 2; }
});
obj.value = 10;
console.log(obj.value);
// [ 20 ]
Object.create() — create with a prototype:
const proto = {
greet() { return `Hello, ${this.name}`; }
};
const obj = Object.create(proto);
obj.name = 'Alice';
console.log(obj.greet());
// [ Hello, Alice ]
console.log(Object.getPrototypeOf(obj) === proto);
// [ true ]
Object.create(null) — object with no prototype:
const dict = Object.create(null);
dict.key = 'value';
console.log(dict.key);
// [ 'value' ]
console.log(dict.toString);
// [ undefined ] ← no inherited methods
This is useful for pure key-value storage without prototype pollution.
Object.getPrototypeOf and Object.setPrototypeOf:
const proto = { a: 1 };
const obj = { b: 2 };
Object.setPrototypeOf(obj, proto);
console.log(Object.getPrototypeOf(obj) === proto);
// [ true ]
Object.setPrototypeOf is slow — avoid it in hot paths.
Object.hasOwn — own property check (ES2022):
const obj = { a: 1 };
console.log(Object.hasOwn(obj, 'a'));
// [ true ]
console.log(Object.hasOwn(obj, 'toString'));
// [ false ] ← inherited
Replaces the older Object.prototype.hasOwnProperty.call(obj, 'a').
Object.groupBy — group by key (ES2024):
const items = [
{ name: 'apple', type: 'fruit' },
{ name: 'carrot', type: 'vegetable' },
{ name: 'banana', type: 'fruit' }
];
const grouped = Object.groupBy(items, item => item.type);
console.log(grouped);
// [ {
// fruit: [ { name: 'apple', type: 'fruit' }, { name: 'banana', type: 'fruit' } ],
// vegetable: [ { name: 'carrot', type: 'vegetable' } ]
// } ]
Object.groupBy with primitives:
const nums = [1, 2, 3, 4, 5];
const parity = Object.groupBy(nums, n => n % 2 === 0 ? 'even' : 'odd');
console.log(parity);
// [ { odd: [ 1, 3, 5 ], even: [ 2, 4 ] } ]
Complete Example Session
// ============================================
// PART 1: OBJECT.KEYS
// ============================================
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj));
// [ [ 'a', 'b', 'c' ] ]
// ============================================
// PART 2: OBJECT.VALUES
// ============================================
console.log(Object.values(obj));
// [ [ 1, 2, 3 ] ]
// ============================================
// PART 3: OBJECT.ENTRIES
// ============================================
console.log(Object.entries(obj));
// [ [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ] ]
// ============================================
// PART 4: OBJECT.FROMENTRIES
// ============================================
const back = Object.fromEntries([['a', 1], ['b', 2]]);
console.log(back);
// [ { a: 1, b: 2 } ]
// ============================================
// PART 5: OBJECT.ASSIGN
// ============================================
console.log(Object.assign({}, obj, { d: 4 }));
// [ { a: 1, b: 2, c: 3, d: 4 } ]
// ============================================
// PART 6: OBJECT.FREEZE
// ============================================
const frozen = Object.freeze({ a: 1 });
frozen.a = 2;
console.log(frozen.a);
// [ 1 ]
console.log(Object.isFrozen(frozen));
// [ true ]
// ============================================
// PART 7: OBJECT.SEAL
// ============================================
const sealed = Object.seal({ a: 1 });
sealed.a = 2;
sealed.b = 3;
console.log(sealed);
// [ { a: 2 } ]
console.log(Object.isSealed(sealed));
// [ true ]
// ============================================
// PART 8: OBJECT.HASOWN
// ============================================
console.log(Object.hasOwn(obj, 'a'));
// [ true ]
console.log(Object.hasOwn(obj, 'toString'));
// [ false ]
// ============================================
// PART 9: OBJECT.CREATE
// ============================================
const nullProto = Object.create(null);
nullProto.key = 'value';
console.log(nullProto.toString);
// [ undefined ]
// ============================================
// PART 10: OBJECT.DEFINEPROPERTY
// ============================================
const defined = {};
Object.defineProperty(defined, 'x', { value: 42, writable: false });
console.log(defined.x);
// [ 42 ]
defined.x = 99;
console.log(defined.x);
// [ 42 ]
// ============================================
// PART 11: OBJECT.GETOWNPROPERTYDESCRIPTOR
// ============================================
console.log(Object.getOwnPropertyDescriptor({ a: 1 }, 'a'));
// [ { value: 1, writable: true, enumerable: true, configurable: true } ]
// ============================================
// PART 12: OBJECT.IS
// ============================================
console.log(Object.is(NaN, NaN));
// [ true ]
console.log(Object.is(+0, -0));
// [ false ]
// ============================================
// PART 13: OBJECT.GETPROTOTYPEOF
// ============================================
const arr = [1, 2, 3];
console.log(Object.getPrototypeOf(arr) === Array.prototype);
// [ true ]
// ============================================
// PART 14: OBJECT.SETPROTOTYPEOF
// ============================================
const proto = { greet() { return 'hi'; } };
const o = {};
Object.setPrototypeOf(o, proto);
console.log(o.greet());
// [ 'hi' ]
// ============================================
// PART 15: ITERATE WITH ENTRIES
// ============================================
const prices = { apple: 1.5, banana: 0.75 };
for (const [fruit, price] of Object.entries(prices)) {
console.log(`${fruit}: $${price}`);
}
// [ apple: $1.5 ]
// [ banana: $0.75 ]
// ============================================
// PART 16: MAP OVER ENTRIES
// ============================================
const doubled = Object.fromEntries(
Object.entries(prices).map(([k, v]) => [k, v * 2])
);
console.log(doubled);
// [ { apple: 3, banana: 1.5 } ]
// ============================================
// PART 17: FILTER ENTRIES
// ============================================
const mixed = { a: 1, b: null, c: 3, d: undefined };
const clean = Object.fromEntries(
Object.entries(mixed).filter(([_, v]) => v != null)
);
console.log(clean);
// [ { a: 1, c: 3 } ]
// ============================================
// PART 18: OBJECT.GROUPBY
// ============================================
const items = [
{ name: 'apple', type: 'fruit' },
{ name: 'carrot', type: 'vegetable' },
{ name: 'banana', type: 'fruit' }
];
const grouped = Object.groupBy(items, item => item.type);
console.log(Object.keys(grouped));
// [ [ 'fruit', 'vegetable' ] ]
// ============================================
// PART 19: DEEP FREEZE
// ============================================
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach(v => {
if (v && typeof v === 'object') deepFreeze(v);
});
return obj;
}
const nested = deepFreeze({ a: { b: 1 } });
nested.a.b = 99;
console.log(nested.a.b);
// [ 1 ]
// ============================================
// PART 20: FULL SCRIPT
// ============================================
const obj46 = { a: 1, b: 2, c: 3 };
Object.keys(obj46);
Object.values(obj46);
Object.entries(obj46);
Object.fromEntries([['a', 1], ['b', 2]]);
Object.assign({}, obj46, { d: 4 });
Object.freeze(obj46);
Object.seal(obj46);
Object.isFrozen(obj46);
Object.isSealed(obj46);
Object.hasOwn(obj46, 'a');
Object.create(null);
Object.defineProperty(obj46, 'x', { value: 42 });
Object.getOwnPropertyDescriptor(obj46, 'a');
Object.getPrototypeOf(obj46);
Object.setPrototypeOf(obj46, null);
Object.is(1, 1);
Object.is(NaN, NaN);
Object.groupBy([1, 2, 3, 4], n => n % 2 === 0 ? 'even' : 'odd');
Quick Reference
Enumerating
| Method | Returns |
|---|---|
Object.keys(obj) | Keys |
Object.values(obj) | Values |
Object.entries(obj) | [key, value] pairs |
Object.fromEntries(arr) | Object |
Copying / Merging
| Method | Purpose |
|---|---|
Object.assign(target, ...sources) | Copy/merge (mutates target) |
{ ...obj1, ...obj2 } | Spread merge (new object) |
structuredClone(obj) | Deep copy |
Freezing / Sealing
| Method | Add | Modify | Delete |
|---|---|---|---|
Object.freeze | ❌ | ❌ | ❌ |
Object.seal | ❌ | ✅ | ❌ |
Object.preventExtensions | ❌ | ✅ | ✅ |
Checking
| Method | Purpose |
|---|---|
Object.isFrozen(obj) | Fully frozen? |
Object.isSealed(obj) | Sealed? |
Object.isExtensible(obj) | Can add props? |
Object.hasOwn(obj, k) | Own property? |
Properties
| Method | Purpose |
|---|---|
Object.defineProperty | Define one |
Object.defineProperties | Define many |
Object.getOwnPropertyDescriptor | Get descriptor |
Object.getOwnPropertyDescriptors | Get all |
Prototypes
| Method | Purpose |
|---|---|
Object.create(proto) | Create with proto |
Object.create(null) | No prototype |
Object.getPrototypeOf(obj) | Get prototype |
Object.setPrototypeOf(obj, p) | Set prototype |
Comparison
| Method | Purpose |
|---|---|
Object.is(a, b) | Same-value equality |
Object.is(NaN, NaN) | true |
Object.is(+0, -0) | false |
Grouping (ES2024)
| Method | Purpose |
|---|---|
Object.groupBy(arr, fn) | Group into object |
Map.groupBy(arr, fn) | Group into Map |
Descriptor Flags
| Flag | Meaning |
|---|---|
value | Value |
writable | Can change |
enumerable | Visible |
configurable | Can delete/redefine |
get | Getter |
set | Setter |
Best Practices
✅ Do This:
// Use Object.entries for iteration
for (const [k, v] of Object.entries(obj)) { } // ✅
// Use spread for merging
const merged = { ...a, ...b }; // ✅
// Use Object.fromEntries for transforms
Object.fromEntries(Object.entries(o).map(...)); // ✅
// Use Object.freeze for constants
const CONFIG = Object.freeze({ ... }); // ✅
// Use Object.hasOwn for own-property check
Object.hasOwn(obj, 'key'); // ✅
// Use Object.create(null) for dictionaries
const dict = Object.create(null); // ✅
// Use structuredClone for deep copies
const deep = structuredClone(obj); // ✅
// Use Object.is for NaN / -0 comparisons
Object.is(NaN, NaN); // ✅
// Use Object.groupBy for grouping (ES2024)
Object.groupBy(items, i => i.type); // ✅
❌ Don’t Do This:
// Don't use for...in for own properties
for (const k in obj) { } // ⚠️ includes inherited
// Don't use Object.assign without target
Object.assign(source); // ❌ returns source
Object.assign({}, source); // ✅
// Don't expect deep freeze
Object.freeze({ a: { b: 1 } }); // ⚠️ shallow
// obj.a.b = 99 works
// Don't use getPrototypeOf in hot loops
Object.getPrototypeOf(obj); // ⚠️ slow
// Don't use setPrototypeOf
Object.setPrototypeOf(obj, proto); // ⚠️ deoptimizes
// Don't rely on key order for symbols
Object.keys(obj); // ❌ excludes symbols
// Don't check NaN with ===
NaN === NaN; // ❌ always false
Object.is(NaN, NaN); // ✅
// Don't use Object.assign for deep merge
Object.assign({}, nested); // ❌ shallow only
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
Object.assign mutates target | Original changed | Use {} target or spread |
freeze is shallow | Nested still mutable | deepFreeze or structuredClone |
for...in includes inherited | Unexpected keys | Use Object.keys |
Object.keys excludes symbols | Missing keys | Use Object.getOwnPropertySymbols |
| Key order for integer-like | Sorted numerically | Known behavior |
setPrototypeOf slow | Performance hit | Set prototype at creation |
defineProperty non-writable | Silent failure in sloppy mode | Set writable: true or use strict |
Object.is on objects | Compares references | Same as === |
Real-World Examples
1. Object.keys
console.log(Object.keys({ a: 1, b: 2 }));
// [ [ 'a', 'b' ] ]
2. Object.values
console.log(Object.values({ a: 1, b: 2 }));
// [ [ 1, 2 ] ]
3. Object.entries
console.log(Object.entries({ a: 1, b: 2 }));
// [ [ [ 'a', 1 ], [ 'b', 2 ] ] ]
4. Object.fromEntries
console.log(Object.fromEntries([['a', 1], ['b', 2]]));
// [ { a: 1, b: 2 } ]
5. Object.assign
console.log(Object.assign({}, { a: 1 }, { b: 2 }));
// [ { a: 1, b: 2 } ]
6. Object.freeze
const config = Object.freeze({ port: 8080 });
config.port = 9090;
console.log(config.port);
// [ 8080 ]
7. Object.seal
const user = Object.seal({ name: 'Alice' });
user.name = 'Bob';
user.age = 30;
console.log(user);
// [ { name: 'Bob' } ]
8. Object.isFrozen
console.log(Object.isFrozen(Object.freeze({})));
// [ true ]
9. Object.hasOwn
console.log(Object.hasOwn({ a: 1 }, 'a'));
// [ true ]
console.log(Object.hasOwn({ a: 1 }, 'toString'));
// [ false ]
10. Object.create(null)
const dict = Object.create(null);
dict.key = 'value';
console.log(dict.toString);
// [ undefined ]
11. Object.defineProperty
const obj = {};
Object.defineProperty(obj, 'x', { value: 42, writable: false });
console.log(obj.x);
// [ 42 ]
12. Object.getOwnPropertyDescriptor
const desc = Object.getOwnPropertyDescriptor({ a: 1 }, 'a');
console.log(desc.writable);
// [ true ]
13. Object.getPrototypeOf
console.log(Object.getPrototypeOf([]) === Array.prototype);
// [ true ]
14. Object.setPrototypeOf
const proto = { greet() { return 'hi'; } };
const obj = {};
Object.setPrototypeOf(obj, proto);
console.log(obj.greet());
// [ 'hi' ]
15. Object.is
console.log(Object.is(NaN, NaN));
// [ true ]
console.log(Object.is(+0, -0));
// [ false ]
16. Object.groupBy
const nums = [1, 2, 3, 4];
const grouped = Object.groupBy(nums, n => n % 2 === 0 ? 'even' : 'odd');
console.log(grouped);
// [ { odd: [ 1, 3 ], even: [ 2, 4 ] } ]
17. Iterate with entries
const prices = { apple: 1.5, banana: 0.75 };
for (const [fruit, price] of Object.entries(prices)) {
console.log(`${fruit}: $${price}`);
}
// [ apple: $1.5 ]
// [ banana: $0.75 ]
18. Map over entries
const doubled = Object.fromEntries(
Object.entries({ a: 1, b: 2 }).map(([k, v]) => [k, v * 2])
);
console.log(doubled);
// [ { a: 2, b: 4 } ]
19. Filter entries
const mixed = { a: 1, b: null, c: 3 };
const clean = Object.fromEntries(
Object.entries(mixed).filter(([_, v]) => v != null)
);
console.log(clean);
// [ { a: 1, c: 3 } ]
20. Full Script
const obj46 = { a: 1, b: 2, c: 3 };
Object.keys(obj46);
Object.values(obj46);
Object.entries(obj46);
Object.fromEntries([['a', 1], ['b', 2]]);
Object.assign({}, obj46, { d: 4 });
Object.freeze(obj46);
Object.seal(obj46);
Object.isFrozen(obj46);
Object.isSealed(obj46);
Object.hasOwn(obj46, 'a');
Object.create(null);
Object.defineProperty(obj46, 'x', { value: 42 });
Object.getOwnPropertyDescriptor(obj46, 'a');
Object.getPrototypeOf(obj46);
Object.setPrototypeOf(obj46, null);
Object.is(1, 1);
Object.is(NaN, NaN);
Object.groupBy([1, 2, 3, 4], n => n % 2 === 0 ? 'even' : 'odd');
Visual: Object Methods by Category
┌──────────────────────────────────────────────┐
│ ENUMERATE │
│ │
│ Object.keys → [ 'a', 'b' ] │
│ Object.values → [ 1, 2 ] │
│ Object.entries → [ ['a', 1], ['b', 2] ] │
│ Object.fromEntries ← reverse │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ COPY / MERGE │
│ │
│ Object.assign({}, a, b) │
│ { ...a, ...b } │
│ structuredClone(obj) │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ IMMUTABILITY │
│ │
│ Object.freeze → no add/modify/delete │
│ Object.seal → modify only │
│ preventExtensions → no add │
│ Object.isFrozen / isSealed / isExtensible │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ INSPECT │
│ │
│ Object.hasOwn(obj, k) │
│ Object.getPrototypeOf(obj) │
│ Object.getOwnPropertyDescriptor(obj, k) │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ COMPARE / GROUP │
│ │
│ Object.is(a, b) │
│ Object.groupBy(arr, fn) │
│ │
└──────────────────────────────────────────────┘
Visual: Object.freeze vs Object.seal
┌──────────────────────────────────────────────┐
│ Object.freeze │
│ │
│ Add ❌ │
│ Modify ❌ │
│ Delete ❌ │
│ │
│ Fully immutable — safe for constants │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Object.seal │
│ │
│ Add ❌ │
│ Modify ✅ │
│ Delete ❌ │
│ │
│ Fixed shape, mutable values │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Object.preventExtensions │
│ │
│ Add ❌ │
│ Modify ✅ │
│ Delete ✅ │
│ │
│ No new keys — existing keys fully mutable │
│ │
└──────────────────────────────────────────────┘
Summary
| Method | Category | Purpose |
|---|---|---|
Object.keys | Enumerate | Keys |
Object.values | Enumerate | Values |
Object.entries | Enumerate | Pairs |
Object.fromEntries | Enumerate | From pairs |
Object.assign | Copy | Merge (mutates target) |
structuredClone | Copy | Deep copy |
Object.freeze | Immutability | Fully frozen |
Object.seal | Immutability | Modify only |
Object.preventExtensions | Immutability | No add |
Object.isFrozen | Immutability | Check frozen |
Object.isSealed | Immutability | Check sealed |
Object.isExtensible | Immutability | Can add |
Object.hasOwn | Inspect | Own property |
Object.create | Create | With prototype |
Object.defineProperty | Create | Precise descriptor |
Object.getOwnPropertyDescriptor | Inspect | Get descriptor |
Object.getPrototypeOf | Inspect | Get prototype |
Object.setPrototypeOf | Modify | Set prototype |
Object.is | Compare | Same-value |
Object.groupBy | Group | Group into object |
Key takeaways:
Object.keys/values/entriesenumerate own enumerable propertiesObject.fromEntriesis the reverse — perfect for Map/Object conversionsObject.assignmutates the target — use{}or spread for a new objectObject.freezeis shallow — nested objects still mutable; usedeepFreezeorstructuredCloneObject.sealprevents add/delete but allows modifyObject.hasOwn(ES2022) replaceshasOwnProperty.callObject.isdiffers from===forNaNand±0Object.create(null)gives a clean dictionary with no prototypeObject.definePropertyenables getters, setters, non-writable propsObject.groupBy(ES2024) groups an array by a key function- Use
for...ofwithObject.entriesrather thanfor...into avoid inherited keys - Use
structuredClonefor a true deep copy —Object.assignand spread are shallow
Remember: Object is the toolbox for working with objects. Enumerate with keys/values/entries, copy with spread or structuredClone, lock with freeze/seal, inspect with hasOwn/getPrototypeOf/getOwnPropertyDescriptor, compare with Object.is, and group with Object.groupBy. Know the difference between shallow and deep, between enumerable and not, between own and inherited. Master Object.* methods, and you have full control over JavaScript’s most fundamental data structure.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!