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:

  1. Null and Undefined Checks:
    If the collection is null or undefined, the method immediately exits and returns 0.

  2. 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 integer length property (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.
  3. Map and Set Checks:
    If the object is a native ES6 Map or Set, Lodash identifies its internal [[Class]] tag via getTag and reads the native collection.size property.

  4. 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 internal keys method:

    return keys(collection).length;

How keys(collection) Works Internally

The expression keys(collection).length is the core of how plain object length is calculated:

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.