How Lodash isMap Verifies ES6 Map Objects
This article explains how the Lodash JavaScript library implements
its _.isMap method to accurately detect ES6
Map instances. It covers why conventional validation
techniques such as instanceof fall short in modern
JavaScript environments, how Lodash employs internal object tags
([object Map]), and how it leverages Node.js runtime
bindings for optimized type checking across diverse execution
contexts.
The Limitations of
instanceof Map
A common approach to checking if an object is a Map in
standard JavaScript is using the instanceof operator:
value instanceof MapWhile functional within a single execution realm,
instanceof fails when objects cross execution contexts,
such as across different <iframe> elements or Node.js
vm contexts. In those cases, the prototype chain of the
object points to the Map.prototype of its originating
realm, not the current realm, causing instanceof to return
false.
The Lodash Verification Strategy
Lodash's _.isMap avoids cross-realm prototype mismatches
by combining runtime-level utility checks with fallback structural and
internal slot identification.
Internally, _.isMap generally delegates to a base
implementation constructed through several layers:
1. The isObjectLike
Guard
Before inspecting complex prototypes or internal slots, Lodash
applies a lightweight initial check using isObjectLike:
function isObjectLike(value) {
return value != null && typeof value == 'object';
}This immediately excludes primitives (string,
number, boolean, symbol,
undefined) as well as functions and null.
2. Native Node.js
util.types.isMap
In environments where Node.js internal utilities are accessible, Lodash optimizes performance and accuracy by delegating to Node's internal type-checking module:
var nodeIsMap = nodeUtil && nodeUtil.isMap;
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;Node.js provides C++ bindings through util.types.isMap,
which inspects the underlying V8 internal representation directly,
offering virtually zero false positives and high execution speed.
3. The
getTag Fallback via
Object.prototype.toString
When running in browsers or environments lacking Node's native
helpers, Lodash falls back to baseIsMap, which verifies the
internal [[Class]] or Symbol.toStringTag of
the object via an internal getTag function:
var mapTag = '[object Map]';
function baseIsMap(value) {
return isObjectLike(value) && getTag(value) == mapTag;
}Historically, Object.prototype.toString.call(value)
returns "[object Map]" for ES6 Map
instances.
To account for ES6 features such as
Symbol.toStringTag—which allows developers to alter the
string tag of custom objects—Lodash's internal getTag
function handles instances where native tags might be shadowed or
polyfilled. It temporarily masks Symbol.toStringTag if
necessary or checks against known core types to confirm whether the
object is a genuine built-in Map instance rather than a
plain object impersonating one.
Summary
_.isMap verifies ES6 Map objects by:
- Confirming the target is a non-null object using
isObjectLike. - Using Node.js's native
util.types.isMapmethod when available. - Falling back to internal tag resolution
(
getTag(value) === '[object Map]'), ensuring robust cross-realm detection whereinstanceoffails.