Как получить класс объекта в JavaScript?
Я создал объект на JavaScript, но как мне определить класс этого объекта?
Мне нужно что-то аналогичное методу .getClass()
из Java. Как я могу реализовать это в JavaScript?
5 ответ(ов)
`obj.constructor.name` является надежным методом в современных браузерах. Свойство `Function.name` официально было добавлено в стандарт в ES6, что делает этот способ получения класса объекта JavaScript в виде строки соответствующим стандартам. Если объект создан с помощью `var obj = new MyClass()`, то вернётся "MyClass".
Для чисел вернётся "Number", для массивов — "Array", для функций — "Function" и т.д. Он обычно ведёт себя ожидаемым образом. Единственные случаи, когда он может не сработать, — это если объект создан без прототипа с помощью `Object.create(null)` или если объект был инстанцирован из анонимно определённой (безымянной) функции.
Также учтите, что если вы минифицируете свой код, небезопасно сравнивать с жестко закодированными строками типов. Вместо проверки `obj.constructor.name == "MyType"` лучше использовать `obj.constructor.name == MyType.name`. Или просто сравнивайте конструкторы друг с другом, однако это не сработает через границы DOM, так как в каждом DOM создаются отдельные экземпляры функции конструктора.
Функция getNativeClass()
возвращает "undefined" для неопределённых значений и "null" для значений null.
Для всех остальных значений часть CLASSNAME
извлекается из строки вида [object CLASSNAME]
, которая является результатом вызова Object.prototype.toString.call(value)
.
Функция getAnyClass()
работает аналогично getNativeClass()
, но также поддерживает пользовательские конструкторы:
function getNativeClass(obj) {
if (typeof obj === "undefined") return "undefined";
if (obj === null) return "null";
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}
function getAnyClass(obj) {
if (typeof obj === "undefined") return "undefined";
if (obj === null) return "null";
return obj.constructor.name;
}
getNativeClass("") === "String"; // для пустой строки
getNativeClass(true) === "Boolean"; // для булевого значения
getNativeClass(0) === "Number"; // для числа 0
getNativeClass([]) === "Array"; // для массива
getNativeClass({}) === "Object"; // для объекта
getNativeClass(null) === "null"; // для null
getAnyClass(new (function Foo(){})) === "Foo"; // для экземпляра функции Foo
getAnyClass(new class Foo{}) === "Foo"; // для экземпляра класса Foo
// и так далее...
Таким образом, обе функции могут использоваться для определения типа объектов, но getAnyClass()
предоставляет более широкие возможности за счёт поддержки пользовательских конструкторов.
Чтобы получить имя класса экземпляра, мы можем использовать instance.constructor.name
, как показано в следующем примере:
class Person {
type = "developer";
}
let p = new Person();
console.log(p.constructor.name); // Person
В этом коде мы создаем класс Person
, а затем создаем экземпляр этого класса p
. Используя p.constructor.name
, мы получаем строку с именем класса, в данном случае — "Person".
Чтобы получить "псевдокласс", вы можете обратиться к функции-конструктору, используя
obj.constructor
предполагая, что constructor
установлен правильно при наследовании — что достигается вот так:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Эти две строки, вместе с:
var woofie = new Dog();
обеспечат, что woofie.constructor
будет ссылаться на Dog
. Обратите внимание, что Dog
является функцией-конструктором и представляет собой объект типа Function
. Вы можете сделать проверку, например: if (woofie.constructor === Dog) { ... }
.
Если вам нужно получить имя класса в виде строки, то хорошо работает следующий код:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
Этот код обращается к функции-конструктору, преобразует ее в строку и извлекает имя функции-конструктора.
Стоит отметить, что obj.constructor.name
также мог бы хорошо работать, но это не стандарт. Эта функция поддерживается в Chrome и Firefox, но отсутствует в IE, включая IE 9 и IE 10 RTM.
Вы столкнулись с задачей получения имени класса по его типу, не имея при этом экземпляра объекта. Ваше решение, использующее свойство prototype
и доступ к конструктору, вполне рабочее. Вот ваш код с небольшими пояснениями:
class Test {
// определение вашего класса
}
const nameByType = function(type) {
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test)); // выводит "Test"
Таким образом, вы можете получить имя класса при помощи функции nameByType
, которая принимает тип класса в качестве параметра.
Также, как вы заметили, можно использовать точечную нотацию, что делает код более читаемым:
console.log(Test.prototype.constructor.name); // возвращает "Test"
Оба метода работают эффективно и дают одинаковый результат. Ваш подход к получению имени класса без создания экземпляра объекта вполне корректен.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"