Lodash _.clone vs Shallow Copy Memory References
This article examines how memory referencing operates when using the
Lodash _.clone method on an array of objects compared to
standard shallow copy mechanisms in JavaScript. It outlines how
reference allocation functions at both the array and element levels,
demonstrates why nested object references remain linked, and contrasts
these behaviors with deep cloning alternatives.
The Reality of Lodash
_.clone
In the Lodash library, _.clone is an implementation of a
shallow copy. Consequently, there is no fundamental memory referencing
difference between Lodash's _.clone and native shallow
copying operations, such as the spread operator
([...array]), Array.from(), or
Array.prototype.slice().
Both approaches produce the exact same memory structure when applied to an array containing nested objects.
Outer Array Reference vs. Inner Object References
When you apply _.clone to an array of objects, the
JavaScript engine allocates memory in two distinct ways:
Outer Array (New Memory Address): A new array instance is allocated in heap memory with its own unique memory address. Because the outer reference is unique:
clonedArray === originalArrayevaluates tofalse.- Modifying the array's structure—such as using
push(),pop(), or reordering elements—affects only the cloned array and leaves the original array untouched.
Inner Objects (Shared Memory Addresses): The elements within the array are not duplicated. Instead, the memory addresses (pointers) of the objects stored in the original array are copied directly into the new array. Because these references point to the same memory locations:
clonedArray[0] === originalArray[0]evaluates totrue.- Mutating a property of an inner object (e.g.,
clonedArray[0].name = "Updated") directly alters the object in heap memory, instantly reflecting the change inoriginalArray[0].name.
Memory Behavior Demonstrated
const original = [{ id: 1, name: 'Alpha' }, { id: 2, name: 'Beta' }];
// Using Lodash _.clone
const lodashCloned = _.clone(original);
// Using native shallow copy
const nativeCloned = [...original];
// Array container references are independent
console.log(lodashCloned === original); // false
console.log(nativeCloned === original); // false
// Element references are identical across all instances
console.log(lodashCloned[0] === original[0]); // true
console.log(nativeCloned[0] === original[0]); // true
// Mutating a nested property mutates the shared heap object
lodashCloned[0].name = 'Omega';
console.log(original[0].name); // "Omega"Breaking Object
References with _.cloneDeep
To eliminate shared memory references entirely, a shallow copy is
insufficient. Lodash provides the _.cloneDeep method for
this purpose.
Unlike _.clone, _.cloneDeep recursively
traverses the array and instantiates new memory allocations for every
object and primitive found within. Under _.cloneDeep:
deepClonedArray === originalArrayevaluates tofalse.deepClonedArray[0] === originalArray[0]evaluates tofalse.- Mutating properties inside
deepClonedArraywill have no impact onoriginalArray.