NeuroAgent

How to Check if a Value is an Object in JavaScript

Learn the most reliable methods to detect objects in JavaScript including typeof, instanceof, and Object.prototype.toString(). Handle edge cases like null and arrays effectively.

Question

How can you determine if a value is an object in JavaScript?

NeuroAgent

In JavaScript, you can determine if a value is an object using several methods: the typeof operator, instanceof checks, Object.prototype.toString.call(), and constructor-based approaches. The most reliable methods involve explicitly checking the type while accounting for special cases like null, arrays, and functions which technically return object when using typeof.

Contents

Understanding JavaScript Objects

In JavaScript, objects are complex data types that can store collections of data and more complex entities. An object is a collection of properties, where each property is a key-value pair. Unlike primitive types (string, number, boolean, null, undefined, symbol, bigint), objects are reference types and can have methods and properties.

The key challenge in object detection is that JavaScript has several types that technically behave like objects but aren’t “plain objects” - including arrays, functions, dates, and null. This makes simple type detection unreliable.

javascript
// Different types of objects in JavaScript
const plainObject = { key: 'value' };
const arrayObject = [1, 2, 3];
const functionObject = function() {};
const dateObject = new Date();
const nullObject = null;

Using typeof Operator

The typeof operator is the most basic way to check if a value is an object in JavaScript. However, it has important limitations:

javascript
typeof plainObject;     // "object"
typeof arrayObject;     // "object"
typeof functionObject;  // "function"
typeof dateObject;      // "object"
typeof nullObject;      // "object" - This is a known bug in JavaScript!
typeof undefined;       // "undefined"
typeof 'string';        // "string"
typeof 42;              // "number"
typeof true;            // "boolean"

Important Limitation: The typeof operator returns "object" for all objects, including arrays, dates, and even null. This makes it insufficient for precise object detection without additional checks.

Here’s a basic function using typeof:

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

// Test cases
isObject(plainObject);   // true
isObject(arrayObject);   // true
isObject(nullObject);    // false
isObject(undefined);     // false
isObject('string');      // false

This approach correctly identifies most objects but fails to distinguish between different types of objects.

instanceof Operator

The instanceof operator checks if an object has a specific constructor in its prototype chain. This is useful for checking if an object belongs to a specific class:

javascript
plainObject instanceof Object;      // true
arrayObject instanceof Object;      // true
arrayObject instanceof Array;       // true
functionObject instanceof Object;   // true
functionObject instanceof Function; // true
dateObject instanceof Object;       // true
dateObject instanceof Date;        // true
nullObject instanceof Object;       // false
'hello' instanceof String;          // false (only works with objects created with new)
42 instanceof Number;              // false (only works with objects created with new)

A robust object detection function using instanceof:

javascript
function isObject(value) {
    return value instanceof Object;
}

// Note: This still returns true for arrays, functions, dates, etc.

The instanceof operator is more precise than typeof for distinguishing between objects and primitives, but it doesn’t help differentiate between different types of objects.

Object.prototype.toString.call() Method

This is one of the most reliable methods for type detection in JavaScript. The Object.prototype.toString() method, when called with call(), returns a string indicating the precise type of the object:

javascript
Object.prototype.toString.call(plainObject);     // "[object Object]"
Object.prototype.toString.call(arrayObject);     // "[object Array]"
Object.prototype.toString.call(functionObject);  // "[object Function]"
Object.prototype.toString.call(dateObject);      // "[object Date]"
Object.prototype.toString.call(nullObject);      // "[object Null]"
Object.prototype.toString.call(undefined);       // "[object Undefined]"
Object.prototype.toString.call('hello');         // "[object String]"
Object.prototype.toString.call(42);              // "[object Number]"
Object.prototype.toString.call(true);            // "[object Boolean]"

A comprehensive object detection function:

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

// Test cases
isObject(plainObject);   // true
isObject(arrayObject);   // false
isObject(functionObject); // false
isObject(dateObject);    // false
isObject(nullObject);    // false

This method is excellent for identifying plain objects specifically, but can be adapted for other object types by checking for different return strings.

Object.getPrototypeOf() Method

The Object.getPrototypeOf() method returns the prototype of the specified object. This can be used in object detection:

javascript
Object.getPrototypeOf(plainObject) === Object.prototype;   // true
Object.getPrototypeOf(arrayObject) === Object.prototype;   // false
Object.getPrototypeOf(arrayObject) === Array.prototype;   // true
Object.getPrototypeOf(functionObject) === Object.prototype; // false
Object.getPrototypeOf(functionObject) === Function.prototype; // true
Object.getPrototypeOf(nullObject); // TypeError: Cannot convert undefined or null to object

A function using this approach:

javascript
function isObject(value) {
    try {
        return Object.getPrototypeOf(value) === Object.prototype;
    } catch (e) {
        return false; // Handles null and undefined
    }
}

// Test cases
isObject(plainObject);   // true
isObject(arrayObject);   // false
isObject(functionObject); // false
isObject(nullObject);    // false

This method is useful for checking if an object is a plain object (not from another constructor).

Special Cases and Edge Cases

Several edge cases need special consideration when detecting objects:

Null and Undefined

javascript
typeof null;           // "object" - This is a historical bug in JavaScript
null instanceof Object; // false
Object.prototype.toString.call(null); // "[object Null]"

Arrays

javascript
typeof [];            // "object"
[] instanceof Object; // true
[] instanceof Array;  // true
Object.prototype.toString.call([]); // "[object Array]"

Functions

javascript
typeof function() {}; // "function"
(function() {}) instanceof Object; // true
(function() {}) instanceof Function; // true
Object.prototype.toString.call(function() {}); // "[object Function]"

DOM Elements

javascript
const div = document.createElement('div');
typeof div;                           // "object"
div instanceof Object;                // true
div instanceof HTMLElement;           // true (in browser environment)
Object.prototype.toString.call(div);   // "[object HTMLDivElement]"

Classes and Prototypes

javascript
class MyClass {}
const instance = new MyClass();
typeof instance;                      // "object"
instance instanceof Object;           // true
instance instanceof MyClass;          // true
Object.prototype.toString.call(instance); // "[object Object]"

Best Practices and Recommendations

For Plain Object Detection

If you need to detect plain objects specifically:

javascript
function isPlainObject(value) {
    return Object.prototype.toString.call(value) === '[object Object]' && 
           Object.getPrototypeOf(value) === Object.prototype;
}

For Any Object Detection

If you need to detect any object (including arrays, functions, dates):

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

For Specific Object Types

For detecting arrays specifically:

javascript
function isArray(value) {
    return Array.isArray(value) || 
           Object.prototype.toString.call(value) === '[object Array]';
}

Browser Compatibility Considerations

Some methods like Object.getPrototypeOf() and Object.prototype.toString.call() work consistently across modern browsers, but older environments might require polyfills.

Performance Considerations

  • typeof is the fastest but least reliable
  • instanceof is moderately fast and reliable for constructor checks
  • Object.prototype.toString.call() is the most reliable but slower
  • Choose the method based on your specific needs and performance requirements

Complete Object Detection Utility

Here’s a comprehensive utility that handles all cases:

javascript
const objectTypeDetection = {
    isObject: (value) => value !== null && (typeof value === 'object' || typeof value === 'function'),
    isPlainObject: (value) => Object.prototype.toString.call(value) === '[object Object]' && 
                              Object.getPrototypeOf(value) === Object.prototype,
    isArray: (value) => Array.isArray(value) || 
                        Object.prototype.toString.call(value) === '[object Array]',
    isFunction: (value) => typeof value === 'function' || 
                           Object.prototype.toString.call(value) === '[object Function]',
    isDate: (value) => Object.prototype.toString.call(value) === '[object Date]'
};

Conclusion

Determining if a value is an object in JavaScript requires careful consideration of the detection method based on your specific needs. The typeof operator is quick but unreliable due to its handling of null and its inability to distinguish between different object types. The instanceof operator provides better differentiation but requires knowledge of specific constructors. Object.prototype.toString.call() offers the most precise type detection but is slower. For most practical purposes, combining typeof with null checking provides a good balance of performance and reliability, while Object.prototype.toString.call() is recommended when precise type detection is critical. Always consider the specific requirements of your application and the JavaScript environment you’re working with when choosing an object detection strategy.

Sources

  1. MDN Web Docs - typeof
  2. MDN Web Docs - instanceof
  3. MDN Web Docs - Object.prototype.toString()
  4. MDN Web Docs - Object.getPrototypeOf()
  5. JavaScript.info - Type Conversions
  6. ECMAScript Specification - Object Internal Methods