To efficiently count the number of keys/properties in a JavaScript object, use Object.keys()
combined with the length
property. This method is concise, optimized for performance, and works for most use cases:
const obj = { a: 1, b: 2, c: 3 };
const count = Object.keys(obj).length; // 3
Key Methods & Scenarios
Method | Use Case | Includes Inherited? | Includes Symbols? | Includes Non-Enumerable? |
---|---|---|---|---|
Object.keys(obj).length | Most common: Count own enumerable keys | ❌ | ❌ | ❌ |
Object.getOwnPropertyNames(obj).length | Includes non-enumerable keys (e.g., defined with Object.defineProperty ) | ❌ | ❌ | ✅ |
Reflect.ownKeys(obj).length | Includes symbols and all own keys | ❌ | ✅ | ✅ |
for...in + counter | Rarely needed (inherited keys, but requires hasOwnProperty checks) | ✅* | ❌ | ❌ |
Detailed Breakdown
1. Object.keys(obj).length
(Recommended)
- Efficiency: Fastest method (native implementation).
- Behavior: Returns only own enumerable string-keyed properties.
const obj = { a: 1, b: 2 };
Object.defineProperty(obj, 'hidden', { value: 3, enumerable: false });
console.log(Object.keys(obj).length); // 2 (ignores 'hidden')
2. Object.getOwnPropertyNames(obj).length
- Use Case: Count all own properties (including non-enumerable ones).
const obj = { a: 1 };
Object.defineProperty(obj, 'hidden', { value: 2, enumerable: false });
console.log(Object.getOwnPropertyNames(obj).length); // 2
3. Reflect.ownKeys(obj).length
- Use Case: Includes symbol keys and all own properties.
const sym = Symbol('key');
const obj = { [sym]: 1, a: 2 };
console.log(Reflect.ownKeys(obj).length); // 2
4. for...in
Loop (Not Recommended for Efficiency)
- Use Case: Rare scenarios requiring inherited keys (with checks).
let count = 0;
for (const key in obj) {
if (obj.hasOwnProperty(key)) count++;
}
console.log(count);
Performance Comparison
Method | Speed (Relative) | Memory Use |
---|---|---|
Object.keys().length | Fastest ✅ | Low |
Reflect.ownKeys().length | Slightly slower | Moderate |
for...in + counter | Slowest | Low |
Edge Cases
- Empty Object: Returns
0
. null
/undefined
: Throws an error. Guard with optional chaining:
const count = Object.keys(obj || {}).length;
- Symbols: Use
Reflect.ownKeys()
if symbols are present.
Example Workflow
// Example object with mixed properties
const obj = { a: 1 };
Object.defineProperty(obj, 'hidden', { value: 2, enumerable: false });
const sym = Symbol('secret');
obj[sym] = 3;
// Count enumerable string keys
console.log(Object.keys(obj).length); // 1 ('a')
// Count all own string keys (including non-enumerable)
console.log(Object.getOwnPropertyNames(obj).length); // 2 ('a', 'hidden')
// Count all own keys (including symbols)
console.log(Reflect.ownKeys(obj).length); // 3 ('a', 'hidden', Symbol(secret))
Final Recommendation
Use Object.keys(obj).length
for 99% of cases. For advanced scenarios (symbols or non-enumerable properties), use Reflect.ownKeys()
or Object.getOwnPropertyNames()
. Avoid for...in
unless explicitly handling inherited properties.