← Назад к вопросам

Как определить является ли объект экземпляром определенного класса?

2.2 Middle🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проверка экземпляра класса

В JavaScript есть несколько способов определить, является ли объект экземпляром определенного класса. Каждый метод имеет свои особенности и область применения.

instanceof — основной оператор

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

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

const john = new User('John');

console.log(john instanceof User); // true
console.log(john instanceof Object); // true (все объекты наследуют Object)
console.log({} instanceof User); // false

Это самый надежный способ для классов и функций-конструкторов.

constructor.name — проверка имени класса

constructor свойство указывает на функцию-конструктор объекта.

class Animal {}
class Dog extends Animal {}

const dog = new Dog();

console.log(dog.constructor === Dog); // true
console.log(dog.constructor.name); // "Dog"
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true

Object.getPrototypeOf() — получение прототипа

Получает прототип объекта и можно проверить его свойства.

class User {}
const john = new User();

const proto = Object.getPrototypeOf(john);
console.log(proto.constructor === User); // true

// Или проверить цепочку прототипов
function isInstanceOf(obj, Class) {
  let currentProto = Object.getPrototypeOf(obj);
  while (currentProto !== null) {
    if (currentProto === Class.prototype) return true;
    currentProto = Object.getPrototypeOf(currentProto);
  }
  return false;
}

Symbol.hasInstance — кастомная проверка

Можно переопределить поведение instanceof через Symbol.hasInstance.

class CustomClass {
  static [Symbol.hasInstance](obj) {
    // Кастомная логика
    return obj && obj.type === 'special';
  }
}

const obj = { type: 'special', data: 123 };
console.log(obj instanceof CustomClass); // true

const wrongObj = { type: 'normal', data: 456 };
console.log(wrongObj instanceof CustomClass); // false

Сравнение методов

МетодИспользованиеПлюсыМинусы
instanceofobj instanceof ClassПроверяет всю цепочку наследованияМожет не работать с iframe
constructorobj.constructor === ClassПростая проверкаНе проверяет наследование
getPrototypeOfObject.getPrototypeOf(obj)Явная работа с прототипомСложнее для читаемости
Symbol.hasInstanceКастомная логикаГибкая проверкаУсложняет код

Практические примеры

Иерархия классов

class Animal {
  move() { console.log('Moving...'); }
}

class Dog extends Animal {
  bark() { console.log('Woof!'); }
}

const dog = new Dog();

// instanceof проверяет всю цепочку
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true

// constructor проверяет только прямого родителя
console.log(dog.constructor === Dog); // true
console.log(dog.constructor === Animal); // false

Функция-утилита для проверки

function createInstanceChecker(Class) {
  return function isInstance(obj) {
    if (obj === null || obj === undefined) return false;
    return obj instanceof Class || obj.constructor === Class;
  };
}

const isUser = createInstanceChecker(User);
const isAdmin = createInstanceChecker(Admin);

const user = new User();
console.log(isUser(user)); // true
console.log(isAdmin(user)); // false

Обработка ошибок и граничные случаи

class Request {}

const obj1 = new Request(); // Истинный экземпляр
const obj2 = {}; // Обычный объект
const obj3 = null; // null
const obj4 = undefined; // undefined

// Безопасная проверка
function safeInstanceCheck(obj, Class) {
  try {
    return obj instanceof Class;
  } catch (e) {
    // iframe, cross-realm objects
    return obj && obj.constructor && obj.constructor.name === Class.name;
  }
}

console.log(safeInstanceCheck(obj1, Request)); // true
console.log(safeInstanceCheck(obj2, Request)); // false
console.log(safeInstanceCheck(obj3, Request)); // false

Особые случаи

1. Объекты из разных iframe

// instanceof может не работать между iframe
const iframeDoc = document.querySelector('iframe').contentDocument;
const iframeArray = iframeDoc.defaultView.Array;

const arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(arr instanceof iframeArray); // false (!)

// Используй constructor.name в этом случае
console.log(arr.constructor.name === 'Array'); // true

2. Встроенные типы

const date = new Date();
const regex = /test/;
const error = new Error();

console.log(date instanceof Date); // true
console.log(regex instanceof RegExp); // true
console.log(error instanceof Error); // true

Рекомендации

  1. Используй instanceof — это стандартный и надежный способ
  2. Проверяй null/undefined перед instanceof
  3. Для встроенных типов — instanceof работает идеально
  4. Для кроссреалм объектов — используй constructor.name как фалбек
  5. Symbol.hasInstance — только для специальных случаев
Как определить является ли объект экземпляром определенного класса? | PrepBro