How Lodash _.size Calculates Object Length
The Lodash _.size method calculates the size of a
collection by determining its data type and applying the appropriate
measurement strategy. While arrays and strings have a native
length property, standard JavaScript objects do not. This
article breaks down the internal mechanism Lodash uses to determine the
number of properties in a standard object, detailing the steps from type
checking to counting own enumerable keys.
The Problem with Standard Objects
In JavaScript, plain objects do not possess a built-in
.length property. Attempting to access
{ a: 1, b: 2 }.length returns undefined. To
find the size of a plain object, an algorithm must inspect the object's
keys and count how many own enumerable properties exist.
Step-by-Step Mechanism of
_.size
When you pass an argument to _.size(collection), Lodash
executes the following sequence:
Null and Undefined Checks:
If the collection isnullorundefined, the method immediately exits and returns0.Array-Like Checks:
Lodash checks if the value is array-like using an internal helper (isArrayLike). An object is considered array-like if it is not a function and has a valid, non-negative integerlengthproperty (such as arrays, arguments objects, or strings).- For strings, it handles Unicode characters properly using a string size helper.
- For arrays and other array-like structures, it directly reads
collection.length.
Map and Set Checks:
If the object is a native ES6MaporSet, Lodash identifies its internal[[Class]]tag viagetTagand reads the nativecollection.sizeproperty.Plain Object Resolution:
When the input is a standard key-value object (which is neither array-like nor a Map/Set), Lodash delegates the calculation to its internalkeysmethod:return keys(collection).length;
How
keys(collection) Works Internally
The expression keys(collection).length is the core of
how plain object length is calculated:
- Retrieving Keys: The
keysfunction extracts all of the object’s own enumerable string-keyed property names. In modern environments, this behaves essentially like the nativeObject.keys(object). - Excluding Prototype Properties: Properties inherited through the prototype chain are excluded from this array.
- Excluding Symbol Properties: Standard
Object.keys(and Lodash's basekeysfunction) only retrieves string keys, ignoringSymbolkeys. - Array Length Evaluation: Once the array of key
names is created, JavaScript reads the
.lengthof that array and returns it as an integer representing the size of the object.
Summary of the Source Logic
Under the hood, the implementation functions similarly to this simplified representation:
function size(collection) {
if (collection == null) {
return 0;
}
if (isArrayLike(collection)) {
return isString(collection) ? stringSize(collection) : collection.length;
}
const tag = getTag(collection);
if (tag === '[object Map]' || tag === '[object Set]') {
return collection.size;
}
return Object.keys(collection).length;
}For plain JavaScript objects, Lodash calculates the size by extracting the object's own enumerable properties into an array and returning the length of that array.