← Назад к вопросам
Как определить является ли объект экземпляром определенного класса?
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
Сравнение методов
| Метод | Использование | Плюсы | Минусы |
|---|---|---|---|
| instanceof | obj instanceof Class | Проверяет всю цепочку наследования | Может не работать с iframe |
| constructor | obj.constructor === Class | Простая проверка | Не проверяет наследование |
| getPrototypeOf | Object.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
Рекомендации
- Используй instanceof — это стандартный и надежный способ
- Проверяй null/undefined перед instanceof
- Для встроенных типов — instanceof работает идеально
- Для кроссреалм объектов — используй constructor.name как фалбек
- Symbol.hasInstance — только для специальных случаев