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:
- Primitive-to-Primitive: Comparing identical
BigIntprimitives returnstrue._.isEqual(42n, 42n); // true - Type Discrepancies: Comparing a
BigIntto a standard JavaScriptNumberof the same mathematical value returnsfalsebecause strict type equality is enforced._.isEqual(42n, 42); // false - Wrapped Objects: Comparing wrapped
BigIntobjects (Object(42n)) with primitiveBigIntvalues returnsfalse. 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 unexpectedtruecomparisons between differing wrapped values if both possess no enumerable properties.
Summary of Behavior
- Primitive
BigInt(10n): Fully supported._.cloneand_.cloneDeepcopy them intact by value;_.isEqualcompares them strictly by value and type. - Wrapped
BigIntObjects (Object(10n)): Unsupported. Deep cloning will convert them to{}and equality checks will yield inaccurate results. - Serialization Warning: While Lodash functions clone
BigIntproperly, any custom clones that fallback toJSON.stringify()elsewhere in a pipeline will fail, asBigIntis not JSON-serializable by default.