Why Lodash _.isObject Returns True for Functions
In JavaScript development, developers often expect an object to mean
purely key-value collections, leading to confusion when utility
functions behave differently. This article explains why Lodash's
_.isObject method evaluates functions as true,
detailing the underlying ECMAScript specification, JavaScript's
primitive versus reference type model, and the alternative Lodash
methods available for more restrictive type checking.
Functions Are Objects in JavaScript
The primary reason _.isObject returns true
for a function is that functions in JavaScript are fundamentally
objects. Specifically, a function is a "callable object"—a standard
JavaScript object equipped with an internal [[Call]] method
that allows it to be invoked.
Because functions inherit from Function.prototype, which
in turn inherits from Object.prototype, any function is an
instance of the Object constructor:
function sampleFunction() {}
console.log(sampleFunction instanceof Object); // trueFunctions can have properties and methods assigned to them just like any standard object:
sampleFunction.customProperty = "Hello";
console.log(sampleFunction.customProperty); // "Hello"ECMAScript Specification and Type Checks
JavaScript divides data into two distinct categories: primitives and objects.
- Primitives:
string,number,bigint,boolean,symbol,null, andundefined. - Objects: Everything else, including plain objects, arrays, dates, regular expressions, and functions.
While the native typeof operator returns
'function' for callable objects, the ECMAScript language
specification classifies functions under the broader Object
type.
Lodash adheres strictly to this language-level definition. The
internal implementation of _.isObject checks whether a
value is not a primitive:
// Simplified representation of Lodash's _.isObject
function isObject(value) {
const type = typeof value;
return value != null && (type === 'object' || type === 'function');
}By design, _.isObject answers the question: Is this
value a non-primitive reference type? Because functions are
non-primitive, the method returns true.
Alternatives for Strict Type Checking
If your goal is to distinguish plain data structures from functions or arrays, Lodash provides alternative methods tailored to specific use cases:
_.isPlainObject(value): Checks whethervalueis a plain object created by theObjectconstructor or with an[[Object: null prototype]]. This will returnfalsefor functions, arrays, and class instances._.isFunction(value): Checks specifically if a value is a callable function._.isObjectLike(value): Checks if a value is object-like (typeofis'object'and notnull). Becausetypeofa function is'function',_.isObjectLikereturnsfalsefor functions, buttruefor plain objects, arrays, and regexes.