#6228·lodash

_.cloneDeep does not deep clone Map keys (only values)

Author: MaansiBishtCreated Jun 3, 2026Updated Jul 20, 2026
Labelsenhancement

_.cloneDeep does not deep-clone Map keys (only values) - inconsistency with Set handling

Description

_.cloneDeep deep-clones Map values but does NOT deep-clone Map keys. This creates an inconsistency:

  • Set items → deep-cloned ✓
  • Map values → deep-cloned ✓
  • Map keys → shared reference ✗

In my understanding i think there is a trade-off here - if keys are cloned, the original key references can't be used for .get() on the clone. However:

  1. This is inconsistent with how lodash handles Sets (Set items are cloned, despite the same identity lookup concern for .has())
  2. This deviates from structuredClone() behavior (which deep-clones Map keys)
  3. This means cloneDeep doesn't produce a fully independent copy --> mutations to the original's key objects corrupt the clone

At minimum, this behaviour should be documented. Ideally, it should match Set handling for consistency.

Reproduction

javascript
const _ = require('lodash');

// Map keys: NOT deep-cloned
const key = { id: 1 };
const map = new Map([[key, 'value']]);
const clone = _.cloneDeep(map);
console.log(key === [...clone.keys()][0]); // true --> shared reference

key.id = 999;
console.log([...clone.keys()][0].id); // 999 --> clone corrupted

// Set items: ARE deep-cloned (inconsistency)
const item = { id: 1 };
const set = new Set([item]);
const setClone = _.cloneDeep(set);
console.log(item === [...setClone][0]); // false --> properly independent

Comparison with structuredClone

javascript
const key = { id: 1 };
const map = new Map([[key, 'value']]);
const clone = structuredClone(map);

key.id = 999;
console.log([...clone.keys()][0].id); // 1 --> correctly independent

Root cause

lodash.js line ~2723 in baseClone:

javascript
// Set items ARE cloned:
value.forEach(function(subValue) {
  result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
});

// Map keys are NOT cloned (inconsistency):
value.forEach(function(subValue, key) {
  result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
});

Suggested resolution

Either:

  1. Clone Map keys (matching Set behavior and structuredClone):
javascript
result.set(
  baseClone(key, bitmask, customizer, key, value, stack),
  baseClone(subValue, bitmask, customizer, key, value, stack)
);
  1. Or document that Map keys are intentionally not cloned, and explain why.

Environment

  • lodash 4.18.1
  • Node.js v24.1.0