# JavaScript typeof vs instanceof: How to Check Types Correctly

Source: https://devdocs10.com/articles/javascript/js-typeof  
By Murat Bo · Published 2026-06-25 · DevDocs10 (https://devdocs10.com)

JavaScript gives you two common ways to inspect values: `typeof` and `instanceof`. They look similar at first, but they answer different questions, and using the wrong one can lead to confusing bugs in type checks, validation code, and error handling.

> **Quick answer:** Use `typeof` for primitive values and functions, such as strings, numbers, booleans, and functions. Use `instanceof` to check whether an object comes from a particular constructor or class through its prototype chain.

> **Difficulty:** Beginner
>
> **You'll understand this better if you know:** basic JavaScript values, objects, and how functions and classes create instances.

## 1. What Are `typeof` and `instanceof`?

`typeof` is a unary operator that returns a string describing the general type of a value. `instanceof` is an operator that checks whether an object was created by a particular constructor function or class, or inherits from it through the prototype chain.

- `typeof` answers: “What broad kind of value is this?”
- `instanceof` answers: “Is this object related to this constructor or class?”
- `typeof` works best with primitives and functions.
- `instanceof` works best with objects.
- They are not interchangeable, even when both seem to work in simple examples.

## 2. Why `typeof` and `instanceof` Matter

Type checks are common in input validation, defensive programming, library code, and debugging. If you misunderstand these operators, you may accept the wrong values, reject valid ones, or get misleading results from expressions that seem obvious.

For example, code that checks for an array with `typeof value === "object"` is too broad, because arrays, dates, plain objects, and `null` all behave differently. On the other hand, `instanceof` can tell you whether something is an `Array` or `Date`, but it is less reliable across different execution contexts such as iframes or separate JavaScript realms.

## 3. Basic Syntax

### `typeof` syntax

Use `typeof` directly before a value or expression. It always returns a string.

```javascript
typeof value
```

Common return values include "string", "number", "boolean", "undefined", "symbol", "bigint", "function", and "object".

### `instanceof` syntax

Use `instanceof` between an object and a constructor function or class.

```javascript
value instanceof Constructor
```

The result is a boolean: `true` or `false`.

## 4. Step-by-Step Examples

### Example 1: Checking a primitive with `typeof`

This example shows the most natural use of `typeof`: checking a string.

```javascript
const name = "Ava";

if (typeof name === "string") {
  console.log("Name is a string");
}
```

Output (tested with Node 24.21.0):

```text
Name is a string
```

This works because `typeof` returns a simple type label for primitive values.

### Example 2: Checking a class instance with `instanceof`

Use `instanceof` when you want to know whether an object was created from a specific class.

```javascript
class User {
  constructor(name) {
    this.name = name;
  }
}

const user = new User("Ava");

if (user instanceof User) {
  console.log("This is a User instance");
}
```

Output (tested with Node 24.21.0):

```text
This is a User instance
```

The check succeeds because `user` inherits from `User.prototype`.

### Example 3: Distinguishing arrays from plain objects

A common beginner mistake is using `typeof` to detect arrays. Arrays are objects, so `typeof` does not identify them specifically.

```javascript
const items = [1, 2, 3];

console.log(typeof items); // "object"
console.log(items instanceof Array); // true
```

Output (tested with Node 24.21.0):

```text
object
true
```

In modern JavaScript, `Array.isArray()` is often the best way to check for arrays, but `instanceof Array` still helps you understand the relationship between an array and its constructor.

### Example 4: Checking for built-in object types

`instanceof` is useful for objects like `Date` and `Map`.

```javascript
const createdAt = new Date();
const settings = new Map();

console.log(createdAt instanceof Date); // true
console.log(settings instanceof Map); // true
```

This is a good fit when your logic depends on object behavior that comes from a specific built-in prototype.

## 5. Practical Use Cases

- Validate user input before calling code that expects a string, number, or function.
- Check whether a value is callable before invoking it as a callback.
- Detect whether a value is a class instance in business logic or data transformation code.
- Handle arrays separately from plain objects when normalizing API responses.
- Write safer guard clauses in utility functions and custom validators.

## 6. Common Mistakes

### Mistake 1: Using `typeof` to detect arrays

`typeof` cannot distinguish arrays from plain objects because arrays are objects in JavaScript.

**Problem:** This check treats every object-like value the same, so arrays are misidentified as generic objects.

```javascript
const value = [1, 2];

if (typeof value === "object") {
  console.log("It is an object");
}
```

Output (tested with Node 24.21.0):

```text
It is an object
```

**Fix:** Use `Array.isArray()` when you specifically want to know whether a value is an array.

```javascript
const value = [1, 2];

if (Array.isArray(value)) {
  console.log("It is an array");
}
```

Output (tested with Node 24.21.0):

```text
It is an array
```

The corrected version works because `Array.isArray()` is the dedicated array check.

### Mistake 2: Expecting `typeof null` to return `"null"`

`null` is a historical JavaScript quirk. It returns `"object"` from `typeof`, which often surprises beginners.

**Problem:** This logic assumes `null` has its own type label, so the check fails to detect empty values correctly.

```javascript
const value = null;

if (typeof value === "null") {
  console.log("No value");
}
```

**Fix:** Check `value === null` directly when you need to detect null specifically.

```javascript
const value = null;

if (value === null) {
  console.log("No value");
}
```

Output (tested with Node 24.21.0):

```text
No value
```

This fix works because strict equality checks the actual value instead of the `typeof` label.

### Mistake 3: Using `instanceof` across different execution contexts

`instanceof` depends on prototype identity. Objects created in another realm, such as an iframe or a different window, may not match the constructor you expect.

**Problem:** An object can be a real array or date in another context and still fail `instanceof` in the current one, producing incorrect results.

```javascript
const value = someValueFromAnotherWindow;

if (value instanceof Array) {
  console.log("This is an array");
}
```

Output (tested with Node 24.21.0):

```text
Uncaught ReferenceError: someValueFromAnotherWindow is not defined
```

**Fix:** Use checks designed for cross-realm safety when possible, such as `Array.isArray()` for arrays or a dedicated brand check for your own data structures.

```javascript
const value = someValueFromAnotherWindow;

if (Array.isArray(value)) {
  console.log("This is an array");
}
```

Output (tested with Node 24.21.0):

```text
Uncaught ReferenceError: someValueFromAnotherWindow is not defined
```

The corrected version works better because it does not rely on constructor identity from one specific realm.

## 7. Best Practices

### Practice 1: Use `typeof` for primitives and functions

`typeof` is the simplest and clearest tool for basic runtime checks. It is especially useful before calling a callback or handling text input.

```javascript
function runHandler(handler) {
  if (typeof handler === "function") {
    handler();
  }
}
```

This keeps the check lightweight and easy to read.

### Practice 2: Prefer dedicated helpers for special cases

For arrays, use `Array.isArray()` instead of `instanceof Array` when portability matters.

```javascript
function sum(value) {
  if (!Array.isArray(value)) {
    return 0;
  }

  return value.reduce((total, item) => total + item, 0);
}
```

This is more robust than relying on object constructors alone.

### Practice 3: Validate external data before using it

When data comes from an API, form, or untrusted source, type checks should happen before the value is used.

```javascript
function formatAge(value) {
  if (typeof value !== "number") {
    return "Unknown age";
  }

  return `Age: ${value}`;
}
```

Validating early prevents later runtime errors and makes the function easier to reason about.

## 8. Limitations and Edge Cases

- `typeof null` returns `"object"`, which is a long-standing language quirk.
- `typeof` cannot distinguish arrays, dates, and plain objects.
- `instanceof` depends on the prototype chain, so objects from other realms may fail the check unexpectedly.
- `instanceof` only works with callable constructors or classes on the right-hand side; using a non-constructor can throw an error.
- Objects created with `Object.create(null)` do not inherit from `Object.prototype`, so some assumptions about object methods do not apply.
- Subclassing affects `instanceof` because derived objects are also instances of their parent classes.

## 9. Practical Mini Project

In this mini project, we will build a small validator that classifies a value and returns a readable message. It uses `typeof` for primitives and `instanceof` for object-based checks.

```javascript
class Product {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}

function describeValue(value) {
  if (value === null) {
    return "Value is null";
  }

  if (typeof value === "string") {
    return `Text with length ${value.length}`;
  }

  if (typeof value === "number") {
    return `Number: ${value}`;
  }

  if (value instanceof Product) {
    return `Product: ${value.name} costs ${value.price}`;
  }

  if (Array.isArray(value)) {
    return `Array with ${value.length} items`;
  }

  return "Unknown value type";
}

const items = [
  describeValue("hello"),
  describeValue(42),
  describeValue(new Product("Notebook", 9.99)),
  describeValue([1, 2, 3]),
  describeValue(null)
];

console.log(items);
```

Output (tested with Node 24.21.0):

```text
[ "Text with length 5", "Number: 42", "Product: Notebook costs 9.99", "Array with 3 items", "Value is null" ]
```

This example shows a practical pattern: use `typeof` for primitives, a direct `null` check for null, and `instanceof` for class instances.

## 10. Key Points

- `typeof` returns a string that describes broad JavaScript value categories.
- `instanceof` returns a boolean based on the prototype chain.
- `typeof` is best for primitives and functions.
- `instanceof` is best for checking object instances created by classes or constructors.
- `null` is a special case because `typeof null` returns `"object"`.
- For arrays, `Array.isArray()` is usually the safest choice.
- Cross-realm objects can make `instanceof` less reliable.

## 11. Practice Exercise

- Create a function named `classifyValue`.
- If the input is a string, return `"string"`.
- If the input is a number, return `"number"`.
- If the input is an array, return `"array"`.
- If the input is an instance of a custom class named `Book`, return `"book"`.
- Otherwise return `"unknown"`.

**Expected output:**

```javascript
string
number
array
book
unknown
```

**Hint:** Check primitives with `typeof`, arrays with `Array.isArray()`, and class instances with `instanceof`.

**Solution:**

```javascript
class Book {
  constructor(title) {
    this.title = title;
  }
}

function classifyValue(value) {
  if (typeof value === "string") {
    return "string";
  }

  if (typeof value === "number") {
    return "number";
  }

  if (Array.isArray(value)) {
    return "array";
  }

  if (value instanceof Book) {
    return "book";
  }

  return "unknown";
}

console.log(classifyValue("hello"));
console.log(classifyValue(12));
console.log(classifyValue([1, 2]));
console.log(classifyValue(new Book("JavaScript Guide")));
console.log(classifyValue({}));
```

Output (tested with Node 24.21.0):

```text
string
number
array
book
unknown
```

## 12. Final Summary

`typeof` and `instanceof` solve different problems in JavaScript. `typeof` is the best first check for primitives, functions, and broad value categories, while `instanceof` helps you identify whether an object belongs to a constructor-based type.

They are both useful, but neither one is a universal type checker. `null` needs special handling, arrays are best checked with `Array.isArray()`, and cross-realm objects can make `instanceof` less dependable than it first appears.

When you choose the right check for the job, your validation code becomes clearer, safer, and easier to maintain. As a next step, compare these operators with `Array.isArray()` and `Object.prototype.toString.call()` so you can recognize the tradeoffs between common type-checking techniques.
