countKey
Counts the total number of enumerable properties in an object, including inherited properties. Iterates through all enumerable properties of an object using a for-in loop, counting both own properties and inherited properties from the prototype chain. This provides a fast count when prototype chain properties are intentionally included in the count.
Signature
const countKey: <Type extends object>(object: Type) => number
Parameters
| Name | Type | Description |
|---|---|---|
object | - | The object whose enumerable properties to count |
Returns
The total count of enumerable properties (own + inherited)
Examples
Basic usage with plain objects
import { countKey } from '@winglet/common-utils';
// Plain object with own properties only
const user = { name: 'John', age: 30, active: true };
console.log(countKey(user)); // 3
// Empty object
console.log(countKey({})); // 0
// Object with numeric keys
const scores = { 0: 95, 1: 87, 2: 92 };
console.log(countKey(scores)); // 3
Counting inherited properties from prototype chain
// Object with prototype chain
const parent = { inherited: 'value' };
const child = Object.create(parent);
child.own = 'property';
console.log(countKey(child)); // 2 (includes 'inherited' from parent)
// Constructor function with prototype
function Person(name) {
this.name = name;
}
Person.prototype.species = 'human';
Person.prototype.planet = 'Earth';
const john = new Person('John');
console.log(countKey(john)); // 3 (name + species + planet)
Comparing with Object.keys() for own properties only
const parent = { inherited: 'value' };
const child = Object.create(parent);
child.own1 = 'first';
child.own2 = 'second';
// countKey includes inherited properties
console.log(countKey(child)); // 3
// Object.keys only counts own properties
console.log(Object.keys(child).length); // 2
// For own properties only, use countObjectKey instead
import { countObjectKey } from '@winglet/common-utils';
console.log(countObjectKey(child)); // 2
Performance comparison for large objects
// Create object with many properties
const largeObject = {};
for (let i = 0; i < 10000; i++) {
largeObject[`prop_${i}`] = i;
}
// countKey is faster than Object.keys().length for simple counting
console.time('countKey');
countKey(largeObject); // ~0.5ms
console.timeEnd('countKey');
console.time('Object.keys');
Object.keys(largeObject).length; // ~2ms (creates intermediate array)
console.timeEnd('Object.keys');
Working with objects from Object.create(null)
// Object without prototype
const nullProto = Object.create(null);
nullProto.a = 1;
nullProto.b = 2;
nullProto.c = 3;
console.log(countKey(nullProto)); // 3
// No inherited properties from Object.prototype
console.log('toString' in nullProto); // false
Playground
import { countKey } from '@winglet/common-utils'; // Plain object with own properties only const user = { name: 'John', age: 30, active: true }; console.log(countKey(user)); // 3 // Empty object console.log(countKey({})); // 0 // Object with numeric keys const scores = { 0: 95, 1: 87, 2: 92 }; console.log(countKey(scores)); // 3
Notes
Behavior Details:
- Counts ALL enumerable properties (own + inherited)
- Uses for-in loop for optimal performance
- Does not create intermediate arrays
- Includes properties from entire prototype chain
- Skips non-enumerable properties
- Works with objects created via Object.create(null)
Performance Characteristics:
- Time Complexity: O(n) where n is total enumerable properties
- Space Complexity: O(1) constant space
- ~4x faster than Object.keys().length for counting
- No array allocation overhead
Use Cases:
- Quick property counting when inheritance is intended
- Performance-critical counting operations
- Checking if object has any enumerable properties
- Working with objects that intentionally use prototypes
When to Use countObjectKey Instead:
- Need to count only own properties
- Working with objects that may have unwanted inherited properties
- Need consistent behavior with Object.keys()
- Security-sensitive contexts where prototype pollution is a concern