Существуют ли «гармоничные» способы получения имени класса из экземпляра класса ES6? Кроме как
someClassInstance.constructor.name
В настоящее время я рассчитываю на реализацию Traceur. И кажется, что у Бабеля есть полифилл, Function.name
а у Трейсера нет.
Подводя итог, можно сказать, что в ES6 / ES2015 / Harmony другого пути не было, и в ES.Next ничего не ожидается.
Он может предоставлять полезные шаблоны для незавершенных серверных приложений, но нежелателен в приложениях, предназначенных для браузера / настольного компьютера / мобильного устройства.
Babel используетcore-js
для заполнения Function.name
, он должен быть загружен вручную для приложений Traceur и TypeScript в зависимости от ситуации.
javascript
ecmascript-6
traceur
Настой Эстус
источник
источник
instance.constructor.name
иclass.name
возвращает имя класса в надлежащем ES6.someClassInstance.constructor.name
будет искажено, если вы унизите свой код..constructor
.Ответы:
someClassInstance.constructor.name
это совершенно правильный способ сделать это. Транспортеры могут не поддерживать это, но это стандартный способ согласно спецификации. (name
Свойство функций, объявленных через производства ClassDeclaration, устанавливается в 14.5.15 , шаг 6.)источник
someClassInstance.constructor
- это функция. У всех функций естьname
свойство, для которого установлено его имя. Вот почему Бабел не нужно ничего делать. Пожалуйста, смотрите developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Как говорит @ Domenic, используйте
someClassInstance.constructor.name
. @Esteban упоминает в комментариях, чтоТаким образом, чтобы получить статический доступ к имени класса, сделайте следующее (это работает с моей версией Babel, кстати. Согласно комментариям на @Domenic ваш пробег может отличаться).
Обновить
Вавилон был в порядке, но в конечном итоге у меня возникли проблемы. Я создаю игру и создаю хеш объединенных ресурсов Sprite (где ключ - имя функции). После минификации каждая функция / класс была названа
t
. Это убивает хэш. Я используюGulp
в этом проекте, и после прочтения документации gulp-uglify я обнаружил, что есть параметр, чтобы предотвратить искажение этой локальной переменной / имени функции. Итак, в моем gulpfile я изменился.pipe($.uglify())
в.pipe($.uglify({ mangle: false }))
Здесь есть компромисс между производительностью и удобочитаемостью. Отказ от именования приведет к (немного) большему файлу сборки (больше сетевых ресурсов) и потенциально к более медленному выполнению кода (требуется цитирование - может быть BS). С другой стороны, если бы я сохранил то же самое, мне пришлось бы вручную определять
getClassName
все классы ES6 - на статическом уровне и на уровне экземпляра. Нет, спасибо!Обновить
После обсуждения в комментариях кажется, что отказ от
.name
соглашения в пользу определения этих функций - хорошая парадигма. Это займет всего несколько строк кода и позволит полностью минимизировать и обобщать ваш код (если он используется в библиотеке). Так что, я думаю, я передумал и буду определятьgetClassName
на уроках вручную . Спасибо @estus! , Метод получения / установки обычно является хорошей идеей по сравнению с прямым доступом к переменным в любом случае, особенно в клиентском приложении.источник
reserved
помощью опции Uglify (список классов можно получить с помощью regexp или чего-либо еще).name
шаблона может быть просто беспроигрышной. То же самое можно применить к Node, но в меньшей степени (например, запутанное приложение Electron). Как правило, я полагаюсь наname
код сервера, но не на код браузера и не на общую библиотеку.name
код DRYer для извлечения имени сущности, которая использует класс (service, plugin и т. Д.), Из имени класса, но в итоге я обнаружил, что он явно дублирует его с помощью static prop (id
,_name
) это просто самый солидный подход. Хорошая альтернатива - не обращать внимания на имя класса, использовать сам класс (объект функции) в качестве идентификатора для сущности, которая отображается на этот класс иimport
где это необходимо (подход, который использовался Angular 2 DI).Получение имени класса непосредственно из класса
В предыдущих ответах объяснялось, что
someClassInstance.constructor.name
это прекрасно работает, но если вам нужно программно преобразовать имя класса в строку и не хотите создавать экземпляр только для этого, запомните:И, поскольку каждая функция имеет
name
свойство, другой хороший способ получить строку с именем вашего класса - это просто сделать:Далее следует хороший пример того, почему это полезно.
Загрузка веб-компонентов
Как учит нас документация MDN , вы загружаете веб-компонент следующим образом:
Откуда
YourComponent
идет классHTMLElement
? Поскольку считается хорошей практикой присваивать классу вашего компонента после самого тега компонента, было бы неплохо написать вспомогательную функцию, которую все ваши компоненты могли бы использовать для регистрации самих себя. Итак, вот эта функция:Так что все, что вам нужно сделать, это:
Что приятно, потому что это менее подвержено ошибкам, чем сам тэг компонента. Чтобы обернуть это, это
upperCamelCaseToSnakeCase()
функция:источник
Для трансплантации вавилона (до минификации)
Если вы используете Babel с
@babel/preset-env
, можно сохранить определения классов без преобразования их в функции (что удаляетconstructor
свойство)Вы можете отказаться от совместимости старого браузера с этой конфигурацией в
babel.config / babelrc
:Для минификации вавилона (после транспиляции)
Похоже, что сейчас нет простого решения ... Нам нужно взглянуть на искажения.
источник
class Foo {}
будет уменьшен до чего-то, какclass a{}
с любой целью. Там не будет ниFoo
слова в минимизированном исходном коде.export class Foo{}
они не могут быть эффективно расширены в дальнейшем, но это может отличаться в других местах, мы не можем знать, как именно, не имея четкого представления о том, что происходит с конкретными частями кода во время сборки. В любом случае, это не изменилось с 2015 года. Это всегда было возможно для некоторых конфигураций компиляции и кода. И я бы сказал, что эта возможность все еще слишком хрупкая, чтобы использовать имена классов для логики приложения. Имя класса, на которое вы полагаетесь, может стать мусором после одного случайного изменения исходного кодаconstructor.name
прежнему работает в минимизированной версии ... нелогично: /