Skip to main content

Javascript Object Methods Cheatsheet

Comprehensive reference for JavaScript Object static methods and instance methods including Object.create, Object.assign, Object.keys, Object.entries, Object.freeze, and modern ES6+ methods

Table of Contents


Prerequisites

JavaScript Version: This cheatsheet targets ES2023+. Some methods require specific versions (noted inline).

// Check JavaScript version support
console.log(Object.keys({ a: 1 })); // ES5+
console.log(Object.assign({}, { a: 1 })); // ES6+
console.log(Object.entries({ a: 1 })); // ES2017+
console.log(Object.hasOwn({ a: 1 }, "a")); // ES2022+

Browser Support: Most methods work in modern browsers. Check MDN compatibility for specific versions.


Object Creation Methods

Object.create() πŸ—οΈ

Creates a new object with specified prototype and properties.

// Basic usage - create object with prototype
const proto = { greet: () => "Hello" };
const obj = Object.create(proto);
obj.name = "John";
console.log(obj.greet()); // β†’ 'Hello'
console.log(obj.name); // β†’ 'John'
// Create with null prototype (no inherited properties)
const cleanObj = Object.create(null);
cleanObj.prop = "value";
console.log(cleanObj.toString); // β†’ undefined (no Object.prototype)
// Create with property descriptors
const objWithDesc = Object.create(
{},
{
name: {
value: "Alice",
writable: false,
enumerable: true,
configurable: false,
},
age: {
value: 30,
writable: true,
enumerable: true,
},
},
);
console.log(objWithDesc.name); // β†’ 'Alice'
objWithDesc.name = "Bob"; // ❌ Silent failure (writable: false)
// Create empty object (equivalent to {})
const empty = Object.create(Object.prototype);

Object.assign() πŸ“‹

Copies enumerable own properties from source objects to target object.

// Basic usage - shallow copy
const target = { a: 1 };
const source = { b: 2, c: 3 };
Object.assign(target, source);
console.log(target); // β†’ { a: 1, b: 2, c: 3 }
// Multiple sources (later sources override earlier)
const obj = {};
Object.assign(obj, { a: 1 }, { b: 2 }, { a: 3 });
console.log(obj); // β†’ { a: 3, b: 2 }
// Clone object (shallow copy)
const original = { a: 1, b: { c: 2 } };
const clone = Object.assign({}, original);
clone.b.c = 99;
console.log(original.b.c); // β†’ 99 (shallow copy!)
// Merge with defaults
function createUser(options) {
const defaults = { name: "Anonymous", age: 0, active: true };
return Object.assign({}, defaults, options);
}
const user = createUser({ name: "John", age: 30 });
console.log(user); // β†’ { name: 'John', age: 30, active: true }
// ❌ Don't use for deep cloning
const nested = { a: { b: { c: 1 } } };
const shallow = Object.assign({}, nested);
shallow.a.b.c = 2;
console.log(nested.a.b.c); // β†’ 2 (mutated original!)

Object.fromEntries() πŸ”„

Creates object from array of key-value pairs (inverse of Object.entries).

// Convert array of pairs to object
const entries = [
["name", "John"],
["age", 30],
];
const obj = Object.fromEntries(entries);
console.log(obj); // β†’ { name: 'John', age: 30 }
// Convert Map to object
const map = new Map([
["a", 1],
["b", 2],
]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // β†’ { a: 1, b: 2 }
// Transform object properties
const original = { name: "John", age: 30 };
const transformed = Object.fromEntries(
Object.entries(original).map(([key, value]) => [
key.toUpperCase(),
typeof value === "number" ? value * 2 : value,
]),
);
console.log(transformed); // β†’ { NAME: 'John', AGE: 60 }
// Convert URLSearchParams to object
const params = new URLSearchParams("name=John&age=30");
const paramsObj = Object.fromEntries(params);
console.log(paramsObj); // β†’ { name: 'John', age: 30 }

Property Access Methods

Object.keys() πŸ”‘

Returns array of object’s own enumerable property names.

// Basic usage
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj)); // β†’ ['a', 'b', 'c']
// Iterate over keys
const user = { name: "John", age: 30, city: "NYC" };
Object.keys(user).forEach((key) => {
console.log(`${key}: ${user[key]}`);
});
// β†’ name: John
// β†’ age: 30
// β†’ city: NYC
// Check if object has properties
const isEmpty = (obj) => Object.keys(obj).length === 0;
console.log(isEmpty({})); // β†’ true
console.log(isEmpty({ a: 1 })); // β†’ false
// Get keys in specific order (ES2022+)
const ordered = { 1: "a", 2: "b", 10: "c" };
console.log(Object.keys(ordered)); // β†’ ['1', '2', '10'] (string keys)
// ❌ Doesn't include non-enumerable properties
const objWithHidden = {};
Object.defineProperty(objWithHidden, "hidden", {
value: "secret",
enumerable: false,
});
console.log(Object.keys(objWithHidden)); // β†’ [] (hidden not included)

Object.values() πŸ’Ž

Returns array of object’s own enumerable property values.

// Basic usage
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.values(obj)); // β†’ [1, 2, 3]
// Sum all values
const prices = { apple: 1.5, banana: 0.8, orange: 2.0 };
const total = Object.values(prices).reduce((sum, price) => sum + price, 0);
console.log(total); // β†’ 4.3
// Filter values
const scores = { alice: 95, bob: 87, charlie: 92 };
const highScores = Object.values(scores).filter((score) => score >= 90);
console.log(highScores); // β†’ [95, 92]
// Get unique values
const data = { a: "x", b: "y", c: "x" };
const unique = [...new Set(Object.values(data))];
console.log(unique); // β†’ ['x', 'y']

Object.entries() πŸ“

Returns array of object’s own enumerable [key, value] pairs.

// Basic usage
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.entries(obj)); // β†’ [['a', 1], ['b', 2], ['c', 3]]
// Iterate over entries
const user = { name: "John", age: 30 };
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// β†’ name: John
// β†’ age: 30
// Convert to Map
const obj = { a: 1, b: 2 };
const map = new Map(Object.entries(obj));
console.log(map.get("a")); // β†’ 1
// Filter entries
const scores = { alice: 95, bob: 60, charlie: 92 };
const passed = Object.fromEntries(
Object.entries(scores).filter(([name, score]) => score >= 70),
);
console.log(passed); // β†’ { alice: 95, charlie: 92 }
// Sort by value
const data = { a: 3, b: 1, c: 2 };
const sorted = Object.fromEntries(
Object.entries(data).sort(([, a], [, b]) => a - b),
);
console.log(sorted); // β†’ { b: 1, c: 2, a: 3 }

Object.hasOwn() βœ…

Checks if object has own property (ES2022+ replacement for hasOwnProperty).

// Basic usage
const obj = { a: 1 };
console.log(Object.hasOwn(obj, "a")); // β†’ true
console.log(Object.hasOwn(obj, "toString")); // β†’ false (inherited)
// Safer than hasOwnProperty (works with null prototype)
const nullProto = Object.create(null);
nullProto.prop = "value";
console.log(Object.hasOwn(nullProto, "prop")); // β†’ true
// nullProto.hasOwnProperty('prop'); // ❌ Error: no hasOwnProperty method
// Check multiple properties
const user = { name: "John", age: 30 };
const hasRequired = ["name", "age", "email"].every((prop) =>
Object.hasOwn(user, prop),
);
console.log(hasRequired); // β†’ false (missing email)
// Filter own properties only
const obj = Object.create({ inherited: "value" });
obj.own = "property";
const ownProps = Object.keys(obj).filter((key) => Object.hasOwn(obj, key));
console.log(ownProps); // β†’ ['own']

Object.hasOwnProperty() ⚠️

Legacy method to check own properties (use Object.hasOwn() in ES2022+).

// Basic usage (legacy)
const obj = { a: 1 };
console.log(obj.hasOwnProperty("a")); // β†’ true
// ❌ Problem: fails with null prototype
const nullProto = Object.create(null);
nullProto.prop = "value";
// nullProto.hasOwnProperty('prop'); // TypeError!
// βœ… Safer: use Object.prototype.hasOwnProperty.call()
const safe = Object.prototype.hasOwnProperty.call(nullProto, "prop");
console.log(safe); // β†’ true
// βœ… Best: use Object.hasOwn() (ES2022+)
console.log(Object.hasOwn(nullProto, "prop")); // β†’ true

Property Descriptor Methods

Object.defineProperty() βš™οΈ

Defines new property or modifies existing property with descriptor.

// Basic usage - define property
const obj = {};
Object.defineProperty(obj, "name", {
value: "John",
writable: true,
enumerable: true,
configurable: true,
});
console.log(obj.name); // β†’ 'John'
// Read-only property
const config = {};
Object.defineProperty(config, "apiKey", {
value: "secret123",
writable: false,
enumerable: false,
configurable: false,
});
config.apiKey = "new"; // ❌ Silent failure
console.log(config.apiKey); // β†’ 'secret123'
// Getter and setter
const person = {};
let _age = 0;
Object.defineProperty(person, "age", {
get() {
return _age;
},
set(value) {
if (value < 0) throw new Error("Age cannot be negative");
_age = value;
},
enumerable: true,
configurable: true,
});
person.age = 30;
console.log(person.age); // β†’ 30
// person.age = -5; // ❌ Error: Age cannot be negative
// Computed property
const data = { x: 10, y: 20 };
Object.defineProperty(data, "sum", {
get() {
return this.x + this.y;
},
enumerable: true,
});
console.log(data.sum); // β†’ 30
data.x = 15;
console.log(data.sum); // β†’ 35

Object.defineProperties() πŸ”§

Defines multiple properties at once.

// Define multiple properties
const obj = {};
Object.defineProperties(obj, {
name: {
value: "John",
writable: true,
enumerable: true,
},
age: {
value: 30,
writable: false,
enumerable: true,
},
fullName: {
get() {
return `${this.name} (${this.age})`;
},
enumerable: true,
},
});
console.log(obj.fullName); // β†’ 'John (30)'
// Create immutable configuration
const settings = {};
Object.defineProperties(settings, {
apiUrl: {
value: "https://api.example.com",
writable: false,
configurable: false,
},
timeout: {
value: 5000,
writable: true,
enumerable: true,
},
});

Object.getOwnPropertyDescriptor() πŸ”

Returns property descriptor for own property.

// Get descriptor
const obj = {};
Object.defineProperty(obj, "name", {
value: "John",
writable: false,
enumerable: true,
configurable: true,
});
const desc = Object.getOwnPropertyDescriptor(obj, "name");
console.log(desc);
// β†’ { value: 'John', writable: false, enumerable: true, configurable: true }
// Check if property is writable
function isWritable(obj, prop) {
const desc = Object.getOwnPropertyDescriptor(obj, prop);
return desc ? desc.writable !== false : false;
}
// Get getter/setter
const objWithGetter = {};
let _value = 0;
Object.defineProperty(objWithGetter, "value", {
get() {
return _value;
},
set(v) {
_value = v;
},
enumerable: true,
});
const desc = Object.getOwnPropertyDescriptor(objWithGetter, "value");
console.log(typeof desc.get); // β†’ 'function'

Object.getOwnPropertyDescriptors() πŸ”Ž

Returns all own property descriptors (ES2017+).

// Get all descriptors
const obj = {};
Object.defineProperties(obj, {
a: { value: 1, writable: true },
b: { value: 2, writable: false },
c: {
get() {
return this.a + this.b;
},
enumerable: true,
},
});
const descriptors = Object.getOwnPropertyDescriptors(obj);
console.log(descriptors);
// β†’ { a: {...}, b: {...}, c: {...} }
// Deep clone with descriptors (preserves getters/setters)
function deepClone(obj) {
return Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj),
);
}
const original = {};
Object.defineProperty(original, "prop", {
get() {
return "computed";
},
enumerable: true,
});
const cloned = deepClone(original);
console.log(cloned.prop); // β†’ 'computed'

Iteration Methods

Object.keys() with for…of πŸ”„

Iterate over object keys efficiently.

// Iterate keys
const obj = { a: 1, b: 2, c: 3 };
for (const key of Object.keys(obj)) {
console.log(`${key}: ${obj[key]}`);
}
// Convert to array methods
const data = { x: 10, y: 20, z: 30 };
const doubled = Object.keys(data).reduce((acc, key) => {
acc[key] = data[key] * 2;
return acc;
}, {});
console.log(doubled); // β†’ { x: 20, y: 40, z: 60 }

Object.entries() with for…of πŸ”„

Iterate over key-value pairs.

// Iterate entries
const user = { name: "John", age: 30, city: "NYC" };
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// Transform during iteration
const scores = { alice: 95, bob: 87, charlie: 92 };
const letterGrades = Object.fromEntries(
Object.entries(scores).map(([name, score]) => [
name,
score >= 90 ? "A" : score >= 80 ? "B" : "C",
]),
);
console.log(letterGrades);
// β†’ { alice: 'A', bob: 'B', charlie: 'A' }

Object.getOwnPropertyNames() πŸ“‹

Returns all own property names (including non-enumerable).

// Get all property names
const obj = {};
obj.visible = "visible";
Object.defineProperty(obj, "hidden", {
value: "hidden",
enumerable: false,
});
console.log(Object.keys(obj)); // β†’ ['visible']
console.log(Object.getOwnPropertyNames(obj)); // β†’ ['visible', 'hidden']
// Get all properties including symbols
const sym = Symbol("key");
const obj = { a: 1 };
obj[sym] = "symbol value";
Object.defineProperty(obj, "hidden", {
value: "hidden",
enumerable: false,
});
console.log(Object.getOwnPropertyNames(obj)); // β†’ ['a', 'hidden'] (no symbols)

Object.getOwnPropertySymbols() πŸ”£

Returns array of own symbol properties.

// Get symbol properties
const sym1 = Symbol("key1");
const sym2 = Symbol("key2");
const obj = {
[sym1]: "value1",
[sym2]: "value2",
regular: "regular",
};
console.log(Object.getOwnPropertySymbols(obj)); // β†’ [Symbol(key1), Symbol(key2)]
console.log(Object.keys(obj)); // β†’ ['regular'] (symbols not included)
// Access symbol values
const symbols = Object.getOwnPropertySymbols(obj);
symbols.forEach((sym) => {
console.log(obj[sym]);
});
// β†’ value1
// β†’ value2
// Combine with regular properties
const allKeys = [
...Object.getOwnPropertyNames(obj),
...Object.getOwnPropertySymbols(obj),
];
console.log(allKeys.length); // β†’ 3

Transformation Methods

Object.freeze() ❄️

Freezes object: prevents adding, deleting, or modifying properties.

// Freeze object
const obj = { a: 1, b: 2 };
Object.freeze(obj);
obj.c = 3; // ❌ Silent failure (strict mode throws)
obj.a = 99; // ❌ Silent failure
delete obj.b; // ❌ Silent failure
console.log(obj); // β†’ { a: 1, b: 2 } (unchanged)
// Check if frozen
console.log(Object.isFrozen(obj)); // β†’ true
// Shallow freeze (nested objects not frozen)
const nested = { a: { b: 1 } };
Object.freeze(nested);
nested.a.b = 2; // βœ… Works! (nested object not frozen)
console.log(nested.a.b); // β†’ 2
// Deep freeze helper
function deepFreeze(obj) {
Object.getOwnPropertyNames(obj).forEach((prop) => {
if (obj[prop] !== null && typeof obj[prop] === "object") {
deepFreeze(obj[prop]);
}
});
return Object.freeze(obj);
}

Object.seal() πŸ”’

Seals object: prevents adding or deleting properties, but allows modifying existing.

// Seal object
const obj = { a: 1, b: 2 };
Object.seal(obj);
obj.c = 3; // ❌ Silent failure
obj.a = 99; // βœ… Works (can modify existing)
delete obj.b; // ❌ Silent failure
console.log(obj); // β†’ { a: 99, b: 2 }
// Check if sealed
console.log(Object.isSealed(obj)); // β†’ true
// Difference from freeze
const frozen = Object.freeze({ a: 1 });
const sealed = Object.seal({ a: 1 });
frozen.a = 2; // ❌ Fails
sealed.a = 2; // βœ… Works

Object.preventExtensions() 🚫

Prevents adding new properties (can delete and modify existing).

// Prevent extensions
const obj = { a: 1, b: 2 };
Object.preventExtensions(obj);
obj.c = 3; // ❌ Silent failure
obj.a = 99; // βœ… Works
delete obj.b; // βœ… Works
console.log(obj); // β†’ { a: 99 }
// Check if extensible
console.log(Object.isExtensible(obj)); // β†’ false
// Comparison table
const obj1 = { a: 1 };
const obj2 = { a: 1 };
const obj3 = { a: 1 };
Object.freeze(obj1);
Object.seal(obj2);
Object.preventExtensions(obj3);
// obj1: ❌ add, ❌ delete, ❌ modify
// obj2: ❌ add, ❌ delete, βœ… modify
// obj3: ❌ add, βœ… delete, βœ… modify

Comparison Methods

Object.is() βš–οΈ

Determines if two values are the same value (better than === for NaN and -0).

// Basic comparison
console.log(Object.is(1, 1)); // β†’ true
console.log(Object.is("a", "a")); // β†’ true
console.log(Object.is({}, {})); // β†’ false (different objects)
// NaN comparison (=== fails)
console.log(NaN === NaN); // β†’ false
console.log(Object.is(NaN, NaN)); // β†’ true
// -0 and +0 comparison (=== fails)
console.log(-0 === +0); // β†’ true
console.log(Object.is(-0, +0)); // β†’ false
console.log(Object.is(-0, -0)); // β†’ true
// Use cases
function isNegativeZero(value) {
return Object.is(value, -0);
}
console.log(isNegativeZero(-0)); // β†’ true
console.log(isNegativeZero(0)); // β†’ false
// Array includes uses Object.is internally
const arr = [NaN, -0];
console.log(arr.includes(NaN)); // β†’ true (uses Object.is)
console.log(arr.indexOf(NaN)); // β†’ -1 (uses ===)

Prototype Methods

Object.getPrototypeOf() πŸ”—

Returns prototype of specified object.

// Get prototype
const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // β†’ true
// Check inheritance chain
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
const dog = new Dog();
console.log(Object.getPrototypeOf(dog) === Dog.prototype); // β†’ true
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // β†’ true
// Traverse prototype chain
function getPrototypeChain(obj) {
const chain = [];
let current = obj;
while (current) {
chain.push(current);
current = Object.getPrototypeOf(current);
}
return chain;
}
const chain = getPrototypeChain([]);
console.log(chain.length); // β†’ 3 (Array, Object, null)

Object.setPrototypeOf() πŸ”„

Sets prototype of object (ES6+, use Object.create() when possible).

// Set prototype
const proto = { greet: () => "Hello" };
const obj = {};
Object.setPrototypeOf(obj, proto);
console.log(obj.greet()); // β†’ 'Hello'
// ⚠️ Performance warning: slow operation
// Prefer Object.create() for new objects
const better = Object.create(proto); // βœ… Faster
// Change prototype dynamically
const obj1 = { a: 1 };
const obj2 = { b: 2 };
Object.setPrototypeOf(obj1, obj2);
console.log(obj1.b); // β†’ 2 (inherited)

Object.prototype.isPrototypeOf() πŸ”

Checks if object exists in prototype chain.

// Check prototype chain
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
const dog = new Dog();
console.log(Animal.prototype.isPrototypeOf(dog)); // β†’ true
console.log(Dog.prototype.isPrototypeOf(dog)); // β†’ true
console.log(Object.prototype.isPrototypeOf(dog)); // β†’ true
// vs instanceof
console.log(dog instanceof Dog); // β†’ true
console.log(dog instanceof Animal); // β†’ true

Modern Methods (ES6+)

Object.groupBy() πŸ“Š

Groups array elements by key (ES2023+, experimental).

// Group by property
const inventory = [
{ name: "apples", type: "fruit", quantity: 10 },
{ name: "bananas", type: "fruit", quantity: 5 },
{ name: "carrots", type: "vegetable", quantity: 8 },
];
const grouped = Object.groupBy(inventory, (item) => item.type);
console.log(grouped);
// β†’ {
// fruit: [{ name: 'apples', ... }, { name: 'bananas', ... }],
// vegetable: [{ name: 'carrots', ... }]
// }
// Group by computed value
const numbers = [1, 2, 3, 4, 5, 6];
const evenOdd = Object.groupBy(numbers, (n) => (n % 2 === 0 ? "even" : "odd"));
console.log(evenOdd);
// β†’ { odd: [1, 3, 5], even: [2, 4, 6] }

Spread Operator (…) 🌊

Modern way to copy and merge objects (ES2018+).

// Shallow copy
const original = { a: 1, b: 2 };
const copy = { ...original };
console.log(copy); // β†’ { a: 1, b: 2 }
// Merge objects
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // β†’ { a: 1, b: 3, c: 4 } (obj2 overrides)
// Add properties
const user = { name: "John" };
const withAge = { ...user, age: 30 };
console.log(withAge); // β†’ { name: 'John', age: 30 }
// Conditional properties
const includeExtra = true;
const config = {
base: "url",
...(includeExtra && { extra: "value" }),
};
console.log(config); // β†’ { base: 'url', extra: 'value' }
// ❌ Still shallow copy
const nested = { a: { b: 1 } };
const shallow = { ...nested };
shallow.a.b = 2;
console.log(nested.a.b); // β†’ 2 (mutated!)

Best Practices

βœ… Do’s

// βœ… Use Object.hasOwn() instead of hasOwnProperty (ES2022+)
const obj = { a: 1 };
if (Object.hasOwn(obj, "a")) {
/* ... */
}
// βœ… Use Object.assign() or spread for shallow copies
const copy = { ...original };
// or
const copy = Object.assign({}, original);
// βœ… Use Object.freeze() for constants
const CONFIG = Object.freeze({ apiUrl: "https://api.example.com" });
// βœ… Use Object.entries() for iteration
for (const [key, value] of Object.entries(obj)) {
// ...
}
// βœ… Use Object.fromEntries() for transformations
const transformed = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k.toUpperCase(), v]),
);
// βœ… Check property existence before access
if (Object.hasOwn(obj, "property")) {
// safe to access
}
// βœ… Use Object.create(null) for maps without prototype pollution
const cleanMap = Object.create(null);

❌ Don’ts

// ❌ Don't use hasOwnProperty directly (fails with null prototype)
const nullProto = Object.create(null);
// nullProto.hasOwnProperty('prop'); // TypeError!
// ❌ Don't use Object.assign() for deep cloning
const nested = { a: { b: 1 } };
const shallow = Object.assign({}, nested); // Only shallow copy!
// ❌ Don't mutate frozen/sealed objects
const frozen = Object.freeze({ a: 1 });
// frozen.a = 2; // Silent failure or error
// ❌ Don't use for...in without hasOwnProperty check
for (const key in obj) {
// Includes inherited properties!
if (Object.hasOwn(obj, key)) {
// Now safe
}
}
// ❌ Don't use Object.setPrototypeOf() in hot code paths
// Use Object.create() instead for better performance
// ❌ Don't rely on Object.keys() order for numeric-like keys
const obj = { 2: "b", 1: "a", 10: "c" };
console.log(Object.keys(obj)); // β†’ ['1', '2', '10'] (sorted!)

⚠️ Common Pitfalls

// ⚠️ Object.assign() and spread are shallow copies
const original = { a: { b: 1 } };
const copy = { ...original };
copy.a.b = 2;
console.log(original.a.b); // β†’ 2 (mutated original!)
// ⚠️ Object.freeze() is shallow
const obj = { a: { b: 1 } };
Object.freeze(obj);
obj.a.b = 2; // βœ… Works! (nested not frozen)
console.log(obj.a.b); // β†’ 2
// ⚠️ Object.keys() only returns enumerable own properties
const obj = {};
Object.defineProperty(obj, "hidden", {
value: "secret",
enumerable: false,
});
console.log(Object.keys(obj)); // β†’ [] (hidden not included)
// ⚠️ Object.is() vs ===
console.log(NaN === NaN); // β†’ false
console.log(Object.is(NaN, NaN)); // β†’ true
console.log(-0 === +0); // β†’ true
console.log(Object.is(-0, +0)); // β†’ false
// ⚠️ Object.getOwnPropertyNames() includes non-enumerable
const obj = {};
obj.visible = 1;
Object.defineProperty(obj, "hidden", {
value: 2,
enumerable: false,
});
console.log(Object.keys(obj)); // β†’ ['visible']
console.log(Object.getOwnPropertyNames(obj)); // β†’ ['visible', 'hidden']

🌍 Real-World Use Cases

// Configuration merging with defaults
function createConfig(userConfig) {
const defaults = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
};
return Object.assign({}, defaults, userConfig);
}
// Immutable state updates
function updateUser(state, updates) {
return { ...state, ...updates };
}
// Property validation
function validateRequired(obj, required) {
return required.every((prop) => Object.hasOwn(obj, prop));
}
// Transform API response
function transformResponse(data) {
return Object.fromEntries(
Object.entries(data).map(([key, value]) => [
key.replace(/_/g, ""), // Remove underscores
typeof value === "string" ? value.trim() : value,
]),
);
}
// Create read-only configuration
const CONFIG = Object.freeze({
API_URL: "https://api.example.com",
VERSION: "1.0.0",
});
// Deep equality check (simplified)
function deepEqual(a, b) {
if (Object.is(a, b)) return true;
if (typeof a !== "object" || typeof b !== "object") 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]));
}