How Lodash isArguments Detects Arguments Objects
Lodash’s _.isArguments method determines whether a given
value is a native JavaScript arguments object rather than a
standard array or plain object. This article examines the internal
mechanisms Lodash uses to perform this check, focusing on internal
object tag inspection, null-safe type validation, and fallback property
heuristics designed for edge-case environments.
The Challenge of Arguments Detection
Inside standard JavaScript functions, the arguments
object is an array-like structure containing the parameters passed into
the function. While it possesses a .length property and
indexed elements, it is not an instance of Array, meaning
Array.isArray(arguments) evaluates to false.
Conversely, checking typeof arguments returns
"object", making it indistinguishable from regular objects
using basic language primitives.
Step 1: Validating Object-Like Types
Before attempting to read deep internal properties, Lodash runs the
target value through an isObjectLike check.
function isObjectLike(value) {
return typeof value === 'object' && value !== null;
}This simple gate ensures that primitive types (string,
number, boolean, undefined,
symbol, bigint) and functions are excluded
immediately, preventing TypeError exceptions during
subsequent checks.
Step 2: Checking the
Internal [[Class]] Tag
The primary mechanism Lodash uses to identify an arguments object is
reading its internal [[Class]] or
[Symbol.toStringTag] identifier.
Under the hood, Lodash calls an internal utility, often referred to
as baseGetTag, which executes:
Object.prototype.toString.call(value);For native arguments objects, modern JavaScript engines consistently
return the string "[object Arguments]". If
baseGetTag(value) matches this string and the value is
object-like, Lodash confirms that the value is an arguments
object.
Step 3: Fallback Heuristics for Edge Environments
Some older JavaScript runtimes (such as Internet Explorer 8 and
earlier) or specific polyfilled environments do not return
"[object Arguments]" when calling
Object.prototype.toString. Instead, they might report
"[object Object]".
To ensure broad cross-platform compatibility, Lodash implements a
fallback check based on the unique characteristics of the
arguments object:
- Presence of the
calleeproperty: Nativeargumentsobjects possess a non-enumerablecalleeproperty pointing to the executing function. - Property Ownership Check: Lodash verifies that the
object owns this property using
hasOwnProperty.call(value, 'callee'). - Non-Enumerability Check: Plain objects with a mock
calleeproperty generally make it enumerable. Lodash checks!propertyIsEnumerable.call(value, 'callee').
If an object meets the isObjectLike condition, possesses
an owned callee property, and that property is
non-enumerable, Lodash classifies the object as an arguments object.
Summary of the Flow
When _.isArguments(value) executes, it runs through the
following sequence:
- Returns
falseifvalueisnullor not of type"object". - Checks if
Object.prototype.toString.call(value)equals"[object Arguments]". If it does, returnstrue. - If the primary check fails (in legacy environments), checks whether
the object owns a non-enumerable
calleeproperty without a custom iterator. If so, returnstrue. - Returns
falsefor all other values.