How Lodash isEmpty Handles Empty Map and Set

Lodash's _.isEmpty function evaluates Map and Set instances by identifying their internal object types and checking their native size property. Unlike standard JavaScript objects that rely on enumerable keys to determine emptiness, empty collections created via new Map() or new Set() return true because Lodash detects their specific collection tags and confirms that their size equals 0.

Type Detection via Internal Tags

When a value is passed to _.isEmpty, Lodash first checks for primitive nullish values and general object types. For complex data structures, it uses an internal utility named getTag (which relies on Object.prototype.toString.call(value)) to resolve the exact internal category of the structure.

When evaluating a Map or a Set, the tag resolves to:

This distinction is crucial. Plain JavaScript objects store entries as standard enumerable properties, but Map and Set store entries in internal slots that cannot be discovered using standard methods like Object.keys().

The .size Property Evaluation

Once Lodash identifies an object as a Map or Set, it bypasses standard property enumeration and checks the standard ES6 collection size property:

var tag = getTag(value);
if (tag == mapTag || tag == setTag) {
  return !value.size;
}

In JavaScript, Map.prototype.size and Set.prototype.size return the number of elements contained in the collection:

Because 0 is falsy in JavaScript, the logical NOT operator (!value.size) evaluates to true. When items are added using .set() or .add(), value.size returns an integer greater than 0, causing !value.size to return false.

Why Standard Object Checks Would Fail

If Lodash treated Map and Set as generic objects, _.isEmpty would produce incorrect results. Generic object validation checks the length of own enumerable string-keyed or Symbol-keyed properties:

const map = new Map([['key', 'value']]);
console.log(Object.keys(map).length); // Output: 0

Even though the Map contains an entry, it possesses zero own enumerable properties. By explicitly intercepting the Map and Set tags and checking the .size property directly, Lodash ensures that collections without entries correctly return true, while collections containing entries return false.