Learn JavaScript

instanceof - оператор для проверки связи с конструктором в JavaScript

instanceof проверяет, связан ли объект с конструктором или классом через цепочку прототипов.

Это встроенный оператор JavaScript, который часто используют при работе с классами, конструкторами, наследованием и специальными объектами вроде Date.

Важно: instanceof не отвечает на вопрос “какой это тип вообще?” так же широко, как typeof. Он отвечает на другой вопрос: “есть ли в цепочке прототипов этого значения прототип указанного конструктора?”.

Синтаксис

value instanceof Constructor

Результат всегда будет true или false.

console.log([] instanceof Array); // true
console.log({} instanceof Array); // false

Что делает instanceof

instanceof проверяет, встречается ли Constructor.prototype в цепочке прототипов значения слева.

console.log([] instanceof Array);  // true
console.log([] instanceof Object); // true

Массив связан и с Array, и с Object, потому что массив наследуется от объекта.

Именно поэтому результат иногда бывает true сразу для нескольких проверок.

Пример с классом

Это один из самых типичных случаев использования.

class User {}

const user = new User();

console.log(user instanceof User);   // true
console.log(user instanceof Object); // true

Объект user создан через класс User, а значит проверка на User вернёт true.

Одновременно он всё ещё является объектом, поэтому и instanceof Object тоже даст true.

Пример с функцией-конструктором

instanceof работает не только с классами, но и со старым стилем через функцию-конструктор.

function Animal(name) {
  this.name = name;
}

const cat = new Animal("Milo");

console.log(cat instanceof Animal); // true
console.log(cat instanceof Object); // true

Специальные встроенные объекты

instanceof удобно использовать для объектов, у которых есть свой отдельный конструктор.

const now = new Date();

console.log(now instanceof Date);   // true
console.log(now instanceof Object); // true

Это часто полезно для Date, Map, Set, Error, RegExp и похожих значений.

instanceof и примитивы

Для примитивов instanceof обычно не подходит.

console.log(3 instanceof Number);        // false
console.log("text" instanceof String);   // false
console.log(true instanceof Boolean);    // false
console.log(1n instanceof BigInt);       // false
console.log(Symbol("id") instanceof Symbol); // false

Причина в том, что это примитивные значения, а не объекты-экземпляры.

Примитив и объект-обёртка - не одно и то же

Если создать объект-обёртку через new, результат уже будет другим:

console.log(new Number(3) instanceof Number);     // true
console.log(new String("text") instanceof String); // true
console.log(new Boolean(true) instanceof Boolean); // true

Но в обычном коде такие обёртки почти не используют, потому что они часто создают лишнюю путаницу.

instanceof и null / undefined

Эти значения не имеют цепочки прототипов, поэтому проверка даст false.

console.log(null instanceof Object);      // false
console.log(undefined instanceof Object); // false

Это отличается от typeof null, который возвращает "object".

instanceof и функции

Функции тоже являются объектами, поэтому здесь возможны сразу две истинные проверки:

function greet() {}

console.log(greet instanceof Function); // true
console.log(greet instanceof Object);   // true

То же самое относится и к классам:

class User {}

console.log(User instanceof Function); // true
console.log(User instanceof Object);   // true

instanceof и typeof

Эти операторы решают разные задачи.

console.log(typeof "text");      // "string"
console.log(typeof []);          // "object"
console.log([] instanceof Array); // true
  • typeof удобен для примитивов и функций
  • instanceof удобен для проверки связи объекта с конструктором или классом

Например, для массива typeof не очень полезен, а instanceof Array уже ближе к задаче.

Но для массива ещё надёжнее обычно Array.isArray().

instanceof и Array.isArray()

Для проверки массива часто можно встретить оба варианта:

console.log([] instanceof Array);  // true
console.log(Array.isArray([]));    // true

Оба работают, но для массива обычно предпочитают Array.isArray(), потому что он точнее выражает намерение и лучше подходит именно для этой задачи.

Поэтому в прикладном коде чаще пишут так:

if (Array.isArray(value)) {
  console.log("Это массив");
}

Когда это полезно

instanceof удобно использовать, когда:

  • нужно проверить экземпляр класса
  • важно понять, является ли значение Date, Error, Map, Set и так далее
  • код работает с наследованием и объектами, созданными через конструктор

Пример:

function formatDate(value) {
  if (!(value instanceof Date)) {
    console.log("Ожидался Date");
    return;
  }

  console.log(value.toISOString());
}

Когда этого недостаточно

instanceof не универсален.

Он не подходит, если:

  • нужно проверить примитив вроде строки или числа
  • важно отличить null
  • нужна простая проверка массива без привязки к конструктору

В таких ситуациях обычно используют:

  • typeof для примитивов и функций
  • === null для null
  • Array.isArray() для массивов

Ошибка с правой частью instanceof

Справа от instanceof должен быть корректный конструктор или объект с нужной логикой проверки.

Если поставить неподходящее значение, будет ошибка:

// [] instanceof null; // TypeError
// [] instanceof {};   // TypeError

Поэтому справа обычно стоит именно класс, функция-конструктор или встроенный конструктор вроде Array, Date, Error.

Частые ошибки

Использовать instanceof для примитивов

console.log("text" instanceof String); // false
console.log(3 instanceof Number);      // false

Это не объекты, а примитивы.

Думать, что instanceof проверяет точный “тип вообще”

console.log([] instanceof Array);  // true
console.log([] instanceof Object); // true

Обе проверки истинны, потому что оператор работает через цепочку прототипов.

Проверять массив через instanceof, когда нужен просто массив

console.log([] instanceof Array); // true

Так можно, но в обычном коде чаще и понятнее Array.isArray([]).

Путать примитив и объект-обёртку

console.log("text" instanceof String);        // false
console.log(new String("text") instanceof String); // true

Это разные значения.

Ставить справа не конструктор

// [] instanceof null; // TypeError

Правая часть должна быть корректной для такой проверки.

Быстрая памятка

  • value instanceof Constructor возвращает true или false
  • оператор проверяет связь через цепочку прототипов
  • хорошо подходит для классов, конструкторов, Date, Error, Map, Set
  • не подходит для примитивов вроде строки, числа или boolean
  • [] instanceof Array даёт true, но для массива чаще используют Array.isArray()
  • null instanceof Object даёт false
  • одна и та же сущность может дать true для нескольких проверок, например и для Array, и для Object

Коротко

instanceof - это оператор JavaScript для проверки того, связан ли объект с конструктором или классом через цепочку прототипов. Главное, что стоит запомнить: он полезен для объектов и экземпляров классов, но не подходит для примитивов, а для массива в обычном коде чаще удобнее Array.isArray().