How Lodash _.isObjectLike Excludes Functions

In JavaScript, functions are technically first-class objects, but the Lodash utility method _.isObjectLike explicitly does not treat them as such. This article provides a technical overview of how _.isObjectLike excludes functions, examining the underlying implementation of the function, the mechanics of JavaScript's typeof operator, and how this behavior contrasts with Lodash's broader _.isObject method.

The Underlying Implementation

The implementation of _.isObjectLike in the Lodash source code is remarkably concise:

function isObjectLike(value) {
  return typeof value === 'object' && value !== null;
}

To be considered "object-like," an input must satisfy two strict criteria:

  1. The result of typeof value must strictly equal 'object'.
  2. The value must not be null.

Why typeof Excludes Functions

Under the ECMAScript specification, functions are callable objects that implement the internal [[Call]] method. However, the native typeof operator makes a clear distinction between callable objects and non-callable objects.

According to the ECMAScript specification:

Because typeof returns 'function' for functions, generators, and async functions, evaluating typeof value === 'object' evaluates directly to false. Lodash does not need an explicit negation check (such as typeof value !== 'function') because the language's native operator inherently segregates functions from standard objects.

The null Exclusion

While typeof null === 'object' is a well-known legacy behavior in JavaScript, null is a primitive value and not an object. Lodash handles this by adding value !== null alongside the typeof check. Consequently, only non-primitive, non-callable references pass the conditional statement.

Contrast with _.isObject

Understanding why _.isObjectLike excludes functions is clearer when compared to _.isObject. Lodash defines _.isObject to include any value that is not a primitive:

function isObject(value) {
  const type = typeof value;
  return value != null && (type === 'object' || type === 'function');
}

In _.isObject, Lodash explicitly checks for type === 'function'. By omitting this secondary check in _.isObjectLike, the method restricts its validation exclusively to non-callable object instances such as {} and [], effectively disqualifying functions at the language level.