Skip to main content

How to Check if a Value is a Plain Object in JavaScript

In JavaScript, checking if a value is a "plain" object—meaning an object literal ({...}) or created with new Object()—is not as straightforward as it seems. This is because the typeof operator famously returns 'object' for several different types, including arrays and null.

This guide will teach you the modern, standard, and most reliable method for accurately determining if a value is a plain object. You will also learn why other common approaches, like instanceof, are not suitable for this task.

The Core Problem: The Ambiguity of typeof

The typeof operator is often the first tool developers reach for, but it can be misleading. It returns 'object' for multiple types, not just plain objects.

console.log(typeof {});         // Output: "object" (Correct)
console.log(typeof []); // Output: "object" (This is an array!)
console.log(typeof null); // Output: "object" (This is null!)
console.log(typeof new Date()); // Output: "object" (This is a Date object!)
note

Because of this behavior, a simple typeof value === 'object' check is not sufficient and will lead to bugs.

The most reliable way to check for a plain object is to perform a series of checks that explicitly rule out the other types that typeof misidentifies.

A value is a plain object if and only if:

  1. Its typeof is 'object'.
  2. It is not null.
  3. It is not an Array.

It's a best practice to encapsulate this logic in a reusable function.

function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}

So the solution is the following:

function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}

// Example Usage:
console.log(isObject({ a: 1 })); // Output: true
console.log(isObject(new Object())); // Output: true

console.log(isObject([1, 2, 3])); // Output: false
console.log(isObject(null)); // Output: false
console.log(isObject('hello')); // Output: false

A Robust Alternative: Object.prototype.toString

For a highly precise type check, you can use Object.prototype.toString.call(). This method returns a string that represents the internal [[Class]] of the value, which is a more reliable way to distinguish between object-like types.

Solution:

function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]';
}

// Example Usage:
console.log(isObject({})); // Output: true
console.log(isObject([])); // Output: false (returns '[object Array]')
console.log(isObject(null)); // Output: false (returns '[object Null]')
note

While this method is very accurate, the three-step typeof check is often considered more readable and is more common in modern codebases.

Methods to Avoid

You might see other methods used for this check, but they are generally flawed.

  • instanceof Object: This is unreliable. It returns true for arrays ([] instanceof Object is true) and false for objects created with Object.create(null).
  • lodash.isObject(): The Lodash library's isObject function is much broader. It returns true for almost any object-like value, including arrays, functions, and Date objects, which is not what you want when checking for a plain object.

Conclusion

Accurately checking if a value is a plain object requires you to be explicit and handle JavaScript's quirks.

  • The recommended best practice is the three-step check that combines typeof, a null check, and Array.isArray(): typeof value === 'object' && value !== null && !Array.isArray(value)
  • The Object.prototype.toString.call() method provides a very robust, albeit more verbose, alternative.
  • Avoid using instanceof Object, as its behavior is inconsistent and not suitable for this task.