11

Как получить класс объекта в JavaScript?

10

Я создал объект на JavaScript, но как мне определить класс этого объекта?

Мне нужно что-то аналогичное методу .getClass() из Java. Как я могу реализовать это в JavaScript?

5 ответ(ов)

4
`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 создаются отдельные экземпляры функции конструктора.
0

Функция 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() предоставляет более широкие возможности за счёт поддержки пользовательских конструкторов.

0

Чтобы получить имя класса экземпляра, мы можем использовать instance.constructor.name, как показано в следующем примере:

class Person {
  type = "developer";
}
let p = new Person();

console.log(p.constructor.name); // Person

В этом коде мы создаем класс Person, а затем создаем экземпляр этого класса p. Используя p.constructor.name, мы получаем строку с именем класса, в данном случае — "Person".

0

Чтобы получить "псевдокласс", вы можете обратиться к функции-конструктору, используя

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.

0

Вы столкнулись с задачей получения имени класса по его типу, не имея при этом экземпляра объекта. Ваше решение, использующее свойство 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"

Оба метода работают эффективно и дают одинаковый результат. Ваш подход к получению имени класса без создания экземпляра объекта вполне корректен.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь