Why Lodash isObject Returns False for Null

JavaScript famously evaluates typeof null as "object", a historical design flaw that frequently causes runtime exceptions when accessing properties on non-existent data. The Lodash library resolves this problem with _.isObject, a utility function that strictly categorizes null as false. This article explains the JavaScript language quirk behind null, demonstrates the internal logic Lodash uses to filter it out, and breaks down why this implementation provides safer object verification.

The JavaScript typeof null Bug

In native JavaScript, executing typeof null returns "object". This behavior dates back to the initial 1995 implementation of the language. In the original JavaScript engine, values were represented with a type tag stored in the lower bits of the memory unit. The type tag for an object reference was 000. Because null was represented as a null pointer (0x00 across all bits), its type tag was also read as 000, causing typeof to report it as an object.

Because changing this behavior would break backward compatibility across legacy web applications, ECMAScript has retained the bug. Consequently, relying strictly on typeof value === 'object' in standard JavaScript is unsafe because attempting to access keys or methods on null triggers a TypeError.

How Lodash Implements _.isObject

Lodash avoids this pitfall by pairing a type check with an explicit nullish check. In Lodash's source code, _.isObject is implemented essentially as follows:

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

The function executes two distinct evaluations connected by a logical AND (&&) operator:

  1. value != null: This uses loose inequality (!=) rather than strict inequality (!==). In JavaScript, value != null checks against both null and undefined simultaneously due to type coercion rules. If the input is either null or undefined, this condition immediately short-circuits and evaluates to false.
  2. type === 'object' || type === 'function': If the value is neither null nor undefined, Lodash inspects the output of native typeof. Per the ECMAScript specification, functions are technically callable objects, so Lodash treats them as objects under _.isObject. Plain objects, arrays, regular expressions, and class instances all pass this check.

Evaluation Breakdown by Type

To see how _.isObject categorizes common JavaScript data types:

Safe Object Checking in Practice

By pairing loose inequality checking with native type inspection, _.isObject ensures that any value returning true can be safely treated as an object in memory without immediately throwing a TypeError: Cannot read properties of null. For scenarios where arrays or functions should also be excluded, Lodash provides _.isPlainObject, which inspects the prototype chain, but _.isObject serves as the foundational safeguard against JavaScript's native null misclassification.