Определение класса объекта в JavaScript: аналог .getClass()
Быстрый ответ
Если вам необходимо быстро определить класс объекта в JavaScript, лучше всего использовать свойство yourObject.constructor.name
или метод Object.prototype.toString.call(yourObject)
.
// Пускай вы создали объект 'obj' из класса 'MyClass'
console.log(obj.constructor.name); // Вернет "MyClass" — просто и легко
console.log(Object.prototype.toString.call(obj)); // Вернет "[object MyClass]" — выглядит несколько формальнее
Эти методы идеально подходят для работы с пользовательскими объектами, однако необходимо помнить, что в ходе минификации кода имена конструкторов могут измениться. Используйте .constructor.name
для лучшей читаемости кода и Object.prototype.toString
, если вы ищете большую надежность.
Трудности на пути
Методы constructor.name
и Object.prototype.toString
могут столкнуться с рядом сложностей:
- Минификация кода с помощью инструментов типа UglifyJS может изменить имена функций. Для сохранения их исходных имён применяйте параметр
--mangle false
. - У анонимных функций и переменных нет имени, будто они играют в прятки.
- Объекты, созданные в разных окружениях (например, в iframe), могут быть неопознаваемы, если вы рассчитываете на
constructor.name
. - Если объект создан без прототипа,
constructor.name
вернет "undefined", как будто объект — призрак.
Чтобы минимизировать такие проблемы, вы можете:
- Рассчитывать на идентичность функций, если столкнулись с минификацией кода.
- Проводить прямое сравнение конструкторов — это надежнее, чем полагаться на свойство
name
. - С помощью
Function.prototype.toString()
и регулярных выражений вы можете получить имя функции, что, хотя и менее наглядно, но весьма эффективно.
Разбираемся в структуре объекта
Знакомство с прототипами
Оператор instanceof
позволяет установить, создан ли объект определенным классом или конструктором, как будто проверяя родословную.
console.log(obj instanceof MyClass); // Вернет true, если 'obj' является экземпляром класса 'MyClass'
Создание классов и функций-конструкторов
JavaScript дает возможность создавать объекты с использованием функций-конструкторов или с помощью классов, которые появились начиная с ES6. Предложенные подходы работают с обоими методами создания объектов. Однако не забывайте о совместимости с браузерами при выборе работы с классами.
Визуализация
Дома (🏠) строятся по чертежам (📃):
Дом 🏠: Строится по чертежу класса 📃
Чтобы определить, согласно какому чертежу построен дом, достаточно взглянуть на конструктор:
const myHouse = new HouseBlueprint(); // 🏠 строится по чертежу 📃
Чертеж объекта-дома можно увидеть, оглядев его конструктор:
Чертеж myHouse: **myHouse.constructor**
// Показывает, какому чертежу соответствует ваш 🏠
Так вы легко установите создателя объекта!
Способы решения сложных кейсов
Работа со встроенными типами
Встроенные типы данных, такие как String
, Number
или особняком стоящие Null
and Undefined
, можно определить с помощью функции getNativeClass
:
function getNativeClass(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
Этот подход даст вам возможность точно определить тип данных в JavaScript.
Сложности с наследованием
При работе с наследованием важно укреплять ссылки конструкторов, чтобы instance.constructor.name
корректно указывало класс объекта.
class ParentClass {}
class ChildClass extends ParentClass {
constructor() {
super();
this.constructor = ChildClass;
}
}
Объекты в разных контекстах выполнения
С объектами из внешних контекстов, например, из фреймов или веб-воркеров, небезопасно полагаться на instance.constructor.name
. В таких случаях лучше использовать Object.prototype.toString
или instanceof
для получения ожидаемого результата.
Полезные материалы
- instanceof – JavaScript | MDN — Описание работы оператора
instanceof
. - javascript – Получить имя типа объекта – Stack Overflow — Верный способ определения типа объекта, предлагаемый сообществом.
- ECMAScript 2015 Спецификация языка – ECMA-262 6-е издание — Подробная информация о классах в JavaScript.
- Object.prototype.toString() – JavaScript | MDN — Информация о методе Object.prototype.toString.
- Прототипное наследование — Глубокое погружение в прототипное наследование в JavaScript.
- Понимание классов ES6 и наследования в JavaScript — Изучение классов и наследования ES6.
- 15. Классы — Все, что нужно знать о классах в ES6.