Lodash BigInt Handling: Cloning and Comparison

Lodash handles modern JavaScript BigInt primitives seamlessly in standard cloning and comparison operations, treating them as immutable values much like standard numbers or strings. However, because Lodash v4 predates the official release of ECMAScript 2020, nuances arise when dealing with wrapped BigInt objects (Object(10n)) or operations involving serialization. This article details how Lodash functions like clone, cloneDeep, and isEqual process BigInt primitives and their corresponding object wrappers.

Cloning BigInt Primitives

When using shallow cloning via _.clone() or recursive copying via _.cloneDeep(), Lodash evaluates input values to check if they are complex objects. Because primitive BigInt values (for example, 100n) are primitive types, they return false for _.isObject().

Lodash bypasses deep traversal for primitives and directly returns the original value. Because primitive BigInt values in JavaScript are immutable, retaining the reference by value is standard and safe:

const original = { id: 100n, nested: { count: 500n } };
const cloned = _.cloneDeep(original);

console.log(cloned.id === original.id); // true
console.log(typeof cloned.nested.count); // "bigint"

In any nested data structure, _.cloneDeep() will traverse the surrounding plain objects or arrays and leave the BigInt leaves intact without converting them to standard numbers or throwing type errors.

Cloning BigInt Object Wrappers

JavaScript allows primitives to be wrapped inside an object using Object(100n). Lodash relies on internal tag classification (such as [object Number] or [object String]) via Object.prototype.toString.call() to copy wrapped primitives.

Because Lodash 4 does not include an explicit case for [object BigInt], invoking _.clone() or _.cloneDeep() on an Object(100n) instance treats it as a general object. This results in an empty plain object {} rather than a properly cloned BigInt object instance:

const wrapped = Object(100n);
const clonedWrapped = _.cloneDeep(wrapped);

console.log(clonedWrapped); // {}

Applications should avoid wrapping BigInt inside object wrappers when relying on Lodash for deep cloning.

Comparing BigInts with _.isEqual

Lodash’s _.isEqual() performs deep comparisons using a variation of the SameValueZero equality algorithm for primitive values:

  1. Primitive-to-Primitive: Comparing identical BigInt primitives returns true.
    _.isEqual(42n, 42n); // true
  2. Type Discrepancies: Comparing a BigInt to a standard JavaScript Number of the same mathematical value returns false because strict type equality is enforced.
    _.isEqual(42n, 42); // false
  3. Wrapped Objects: Comparing wrapped BigInt objects (Object(42n)) with primitive BigInt values returns false. When comparing two separate wrapped objects (Object(42n) vs. Object(42n)), Lodash fails to match their internal values due to the missing [object BigInt] tag handler, resulting in unexpected true comparisons between differing wrapped values if both possess no enumerable properties.

Summary of Behavior