Question
How can you determine whether a value is an object in JavaScript? In particular, how should the check handle special cases such as null, arrays, and functions?
Short Answer
You will learn why typeof value === "object" is not always enough, how to exclude null, and how to choose an object check that matches your goal. You will also see how to detect plain objects when arrays, dates, and custom class instances should not be accepted.
Concept
JavaScript has several values that can be described as objects, so the phrase "is an object" needs context.
The most common basic check is:
typeof value === "object" && value !== null
This works because most object values have a typeof result of "object". However, null is a historical JavaScript exception:
console.log(typeof null); // "object"
Therefore, a typeof check alone incorrectly treats null as an object.
A second important detail is that arrays, dates, regular expressions, maps, and class instances are also objects:
typeof []; // "object"
typeof new Date(); // "object"
typeof /pattern/; // "object"
typeof new Map(); // "object"
Functions are also object-like: they can have properties and methods, but typeof reports them as "function" rather than "object".
function greet() {}
greet.language = "en";
console.log(typeof greet); // "function"
console.log(greet.language); // "en"
For this reason, the correct check depends on what your code accepts:
- Accept non-null object values, but not functions: use
typeof value === "object" && value !== null. - Accept objects and functions: check whether the value is non-null and its type is
"object"or"function". - Accept only ordinary object records such as API payloads: use a plain-object check.
Choosing the correct definition prevents validation bugs and makes a function's expected input clear.
Mental Model
Think of JavaScript values as items arriving at a sorting station.
- Numbers, strings, booleans,
undefined, symbols, and bigints are simple individual items: primitives. - Objects are containers that can hold named properties.
- Arrays, dates, maps, and class instances are specialized kinds of containers.
- Functions are machines that can run work, but JavaScript also lets them carry labelled properties, so they are object-like.
nullmeans “no container exists.” Unfortunately, JavaScript's oldtypeoflabel mistakenly says it is an"object".
So typeof value === "object" is like trusting an old, occasionally incorrect sorting label. Add value !== null to reject the empty space, and use a stricter test when only a specific container type is valid.
Syntax and Examples
For a general non-null object check:
function isObject(value) {
return typeof value === "object" && value !== null;
}
console.log(isObject({ name: "Ada" })); // true
console.log(isObject([1, 2, 3])); // true
console.log(isObject(new Date())); // true
console.log(isObject(null)); // false
console.log(isObject("hello")); // false
console.log(isObject(42)); // false
console.(( {}));
Step by Step Execution
Consider this input-validation helper:
function isObject(value) {
return typeof value === "object" && value !== null;
}
const input = null;
const result = isObject(input);
console.log(result);
Execution steps:
inputreceives the valuenull.isObject(input)callsisObject(null).typeof value === "object"evaluates totruebecausetypeof nullis historically"object".value !== nullevaluates tofalsebecause the value is exactlynull.true && falseevaluates tofalse.
Real World Use Cases
- Validating JSON-like API data: Confirm that a response section is an object before reading properties such as
data.user.name. - Configuration options: Ensure a function receives an options object rather than
null, a string, or a number. - Merging settings: Check that a value can be treated as a record before copying its properties.
- Form processing: Validate nested submitted data before accessing optional fields.
- Data transformation: Treat arrays separately from record objects because arrays are usually iterated, while objects are usually accessed by property names.
Example: validate options before using them.
function createConnection(options) {
if (options === null || typeof options !== "object" || Array.isArray(options)) {
throw new TypeError("options must be a plain options object");
}
return {
host: options.host ?? "localhost",
port: options.port ?? 3000
};
}
console.log(createConnection({ host: }));
Real Codebase Usage
In production code, developers usually do not perform an object check merely to label a value. They check it before performing an operation that requires an object.
Guard clauses
A guard clause exits early when input is invalid. This keeps the main logic less nested.
function getDisplayName(user) {
if (user === null || typeof user !== "object") {
return "Guest";
}
return user.name ?? "Guest";
}
Validate the exact shape required
An object check does not prove required properties exist or have the correct types.
function canSendEmail(contact) {
return contact !== null &&
typeof contact === "object" &&
typeof contact.email === "string" &&
contact.email.length > 0;
}
Separate arrays from records
When code expects key-value settings, arrays normally should be rejected.
Common Mistakes
Forgetting that null has type "object"
Broken code:
function isObject(value) {
return typeof value === "object";
}
console.log(isObject(null)); // true — usually unwanted
Fix it by excluding null:
return typeof value === "object" && value !== null;
Assuming arrays are not objects
console.log(typeof []); // "object"
If arrays are invalid, explicitly reject them:
const isRecord = value =>
value !== null &&
typeof value === "object" &&
!.(value);
Comparisons
| Check | Accepts | Rejects | Best use |
|---|---|---|---|
typeof value === "object" | Objects, arrays, null | Functions, primitives | Almost never use alone because of null |
value !== null && typeof value === "object" | Non-null objects, arrays, dates, maps, class instances | null, functions, primitives | Broad object validation |
| `value !== null && (typeof value === "object" | typeof value === "function")` | Objects and functions | |
Array.isArray(value) | Arrays only | Plain objects and other values | Detecting a list |
Cheat Sheet
// Broad check: objects, including arrays and dates; excludes null and functions
const isObject = value => value !== null && typeof value === "object";
// Object-like: includes callable functions too
const isObjectLike = value =>
value !== null &&
(typeof value === "object" || typeof value === "function");
// Arrays only
const isArray = Array.isArray(value);
// Plain object: object literal or Object.create(null)
const isPlainObject = value => {
if (value === null || typeof value !== "object") return false;
const prototype = Object.getPrototypeOf(value);
return prototype === Object.prototype || prototype === null;
};
Key rules:
typeof nullis"object"; always exclude in a normal object check.
FAQ
Why does typeof null return "object" in JavaScript?
It is a long-standing historical behavior in JavaScript. It cannot be changed without breaking existing code, so exclude it explicitly with value !== null.
Is an array an object in JavaScript?
Yes. typeof [] returns "object". Use Array.isArray(value) when you need to specifically detect arrays.
Do functions count as objects in JavaScript?
Functions are object-like because they can have properties, but typeof function () {} returns "function". Include that type only if your use case accepts functions.
What is the best general JavaScript object check?
For non-null objects, use value !== null && typeof value === "object". It is clear and works across realms such as iframes.
How do I check for a plain object in JavaScript?
Check that the value is non-null, has type "object", and has either Object.prototype or null as its prototype. This rejects arrays, dates, and class instances.
Should I use value instanceof Object?
Mini Project
Description
Build a small settings normalizer for a command-line tool or web application. The function will accept a user-provided settings value, safely reject invalid types, and merge valid plain-object settings with defaults. This demonstrates why distinguishing plain objects from null, arrays, and dates matters.
Goal
Create a normalizeSettings function that returns safe settings or throws a useful error for invalid input.
Requirements
- Define default settings with a theme, page size, and notifications flag.
- Accept
undefinedand return the default settings. - Accept only plain objects as custom settings.
- Reject
null, arrays, dates, strings, and numbers with aTypeError. - Merge valid custom settings over the defaults without modifying the default object.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.