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:
value != null: This uses loose inequality (!=) rather than strict inequality (!==). In JavaScript,value != nullchecks against bothnullandundefinedsimultaneously due to type coercion rules. If the input is eithernullorundefined, this condition immediately short-circuits and evaluates tofalse.type === 'object' || type === 'function': If the value is neithernullnorundefined, Lodash inspects the output of nativetypeof. 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:
null: Failsvalue != null, returnsfalse.undefined: Failsvalue != null, returnsfalse.{}(Plain Object): Passesvalue != nulland matchestype === 'object', returnstrue.[](Array): Passesvalue != nulland matchestype === 'object', returnstrue.() => {}(Function): Passesvalue != nulland matchestype === 'function', returnstrue.42or"text"(Primitives): Passesvalue != null, but fails the type check, returningfalse.
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.