How Lodash isEqual Handles Object Key Ordering

This article examines how Lodash’s _.isEqual method performs deep equality comparisons on JavaScript objects, specifically regarding the sequence of object keys. You will learn about the internal mechanism used by Lodash—primarily the baseIsEqualDeep and equalObjects functions—and why key ordering does not affect the outcome of an equality check.

The Core Algorithm: equalObjects

Lodash delegates deep comparison tasks to an internal function named baseIsEqual, which routes object comparisons through baseIsEqualDeep and ultimately to equalObjects.

When comparing two plain objects, the algorithm follows these specific steps:

  1. Key Extraction: The algorithm retrieves the enumerable own property names of both objects using an internal implementation equivalent to Object.keys().
  2. Length Verification: It compares the total number of keys. If the two objects do not have the same number of keys, the comparison immediately returns false.
  3. Key Existence and Value Recursion: The algorithm iterates through the keys of the first object. For each key, it checks whether the second object also possesses that key using hasOwnProperty. If the key exists on both objects, it recursively calls baseIsEqual to compare the corresponding values.
  4. Circular Reference Handling: A tracking stack (via Lodash's internal Stack cache) is used during recursion to detect and safely resolve circular references.

Why Key Ordering Does Not Affect Equality

Even though ECMAScript 2015 (ES6) introduced a deterministic iteration order for object keys in JavaScript, standard objects are fundamentally treated as unordered collections of key-value pairs in computer science and data modeling.

Lodash’s equalObjects algorithm does not compare key lists by index. Instead of asserting that keysA[i] === keysB[i], it verifies that every key present in objectA also exists as an own property in objectB with an equivalent value.

Consider the following example:

const objectA = { a: 1, b: 2 };
const objectB = { b: 2, a: 1 };

_.isEqual(objectA, objectB); // returns true

During execution:

Comparison with Ordered Structures

The algorithm intentionally differentiates between unordered key-value collections (like plain objects) and ordered collections:

By focusing on property membership and recursive value equality rather than iteration order, Lodash ensures that objects representing identical states evaluate as equal, regardless of how or when their properties were defined.