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:

  1. Presence of the callee property: Native arguments objects possess a non-enumerable callee property pointing to the executing function.
  2. Property Ownership Check: Lodash verifies that the object owns this property using hasOwnProperty.call(value, 'callee').
  3. Non-Enumerability Check: Plain objects with a mock callee property 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:

  1. Returns false if value is null or not of type "object".
  2. Checks if Object.prototype.toString.call(value) equals "[object Arguments]". If it does, returns true.
  3. If the primary check fails (in legacy environments), checks whether the object owns a non-enumerable callee property without a custom iterator. If so, returns true.
  4. Returns false for all other values.