Есть ли JavaScript эквивалент Java «с class.getName()
?
javascript
Эвен Картрайт
источник
источник
Ответы:
Нет .
ES2015 Обновление : имя
class Foo {}
естьFoo.name
. Имя классаthing
's', независимо отthing
типа 's', равноthing.constructor.name
. Встроенные конструкторы в среде ES2015 имеют правильноеname
свойство; например(2).constructor.name
есть"Number"
.Но вот различные хаки, которые все так или иначе падают:
Вот хак, который сделает то, что вам нужно - помните, что он изменяет прототип Объекта, что люди не одобряют (обычно по уважительной причине)
Теперь все ваши объекты будут иметь функцию,
getName()
которая будет возвращать имя конструктора в виде строки. Я проверил это в,FF3
иIE7
я не могу говорить о других реализациях.Если вы не хотите этого делать, вот обсуждение различных способов определения типов в JavaScript ...
Я недавно обновил это, чтобы быть немного более исчерпывающим, хотя вряд ли это. Исправления приветствуются ...
Используя
constructor
свойство ...У каждого
object
есть значение для егоconstructor
свойства, но в зависимости от того, как оноobject
было построено, а также от того, что вы хотите сделать с этим значением, оно может быть или не быть полезным.Вообще говоря, вы можете использовать
constructor
свойство для проверки типа объекта следующим образом:Итак, это работает достаточно хорошо для большинства потребностей. Это сказал ...
Предостережения
Во многих случаях не будет работать ВСЕ
Этот паттерн, хотя и нарушен, довольно распространен:
Objects
построенный черезnew Thingy
будет иметьconstructor
свойство, которое указываетObject
, а неThingy
. Таким образом, мы падаем с самого начала; вы просто не можете доверятьconstructor
кодовой базе, которую вы не контролируете.Множественное наследование
Пример, где это не так очевидно, использует множественное наследование:
Вещи теперь не работают, как вы могли бы ожидать, что они:
Таким образом, вы можете получить неожиданные результаты, если
object
ваш тест имеет другойobject
наборprototype
. Есть способы обойти это за рамками этого обсуждения.Существуют и другие варианты использования
constructor
недвижимости, некоторые из которых интересны, другие не так уж много; сейчас мы не будем углубляться в это использование, поскольку оно не имеет отношения к этому обсуждению.Не будет работать поперечина и поперечное окно
Использование
.constructor
проверки типа прекратит работу, если вы захотите проверить тип объектов, поступающих из разныхwindow
объектов, например, из iframe или всплывающего окна. Это потому, чтоconstructor
в каждом «окне» есть разные версии каждого типа ядра , т.е.Использование
instanceof
оператора ...instanceof
Оператор чистый способ тестированияobject
типа , а также, но имеет свои собственные потенциальные проблемы, так же , какconstructor
собственность.Но
instanceof
не работает для литеральных значений (потому что литералы нетObjects
)Например, литералы должны быть обернуты
Object
в,instanceof
чтобы работать.constructor
Проверка работает отлично литералы , так как.
вызов методы неявно упаковывает литералы в соответствующем типе объектаПочему две точки для 3? Потому что Javascript интерпретирует первую точку как десятичную точку;)
Не будет работать поперечина и поперечное окно
instanceof
также не будет работать в разных окнах по той же причине, что иconstructor
проверка свойства.Используя
name
собственностьconstructor
собственности ...Не работает на всех во многих случаях
Опять же, смотрите выше; это довольно распространено для того,
constructor
чтобы быть совершенно и совершенно неправильным и бесполезным.НЕ работает в <IE9
Использование
myObjectInstance.constructor.name
даст вам строку, содержащую название используемойconstructor
функции, но с учетом предостережений относительноconstructor
свойства, которые были упомянуты ранее.Для IE9 и выше вы можете использовать monkey-patch в поддержке :
Обновленная версия из рассматриваемой статьи. Это было добавлено через 3 месяца после публикации статьи, это рекомендуемая версия для использования автором статьи Мэтью Шарли. Это изменение было вдохновлено комментариями, указывающими на возможные подводные камни в предыдущем коде.
Использование Object.prototype.toString
Оказывается, что в этом сообщении вы можете использовать
Object.prototype.toString
- низкоуровневую и обобщенную реализациюtoString
- чтобы получить тип для всех встроенных типовМожно написать короткую вспомогательную функцию, такую как
убрать фуфло и получить только название типа
Тем не менее, он вернется
Object
для всех пользовательских типов.Предостережения для всех ...
Все это связано с одной потенциальной проблемой, и это вопрос о том, как данный объект был построен. Вот различные способы построения объектов и значений, которые будут возвращать различные методы проверки типов:
Хотя в этом наборе примеров присутствуют не все перестановки, надеюсь, их будет достаточно, чтобы дать вам представление о том, как могут возникать беспорядочные вещи в зависимости от ваших потребностей. Ничего не предполагайте, если вы точно не понимаете, что вам нужно, вы можете закончить взломом кода там, где вы этого не ожидаете, из-за отсутствия уловок тонкостей.
НОТА:
Обсуждение
typeof
оператора может показаться явным упущением, но на самом деле бесполезно помогать определить,object
является ли тип заданным, поскольку оно очень упрощенное. Понимание того, гдеtypeof
это полезно, важно, но в настоящее время я не чувствую, что это очень важно для этой дискуссии. Мой разум открыт для изменения, хотя. :)источник
constructor
(либо с помощью,.toString()
либо.name
), не будут работать, если ваш Javascript был уменьшен с помощью такого инструмента, как uglify, или конвейер ресурсов Rails. Минификация переименовывает конструктор, поэтому вы получите неправильные имена классов, такие какn
. Если вы находитесь в этом сценарии, вы можете просто вручную определитьclassName
свойство ваших объектов и использовать его вместо этого.Ответ Джейсона Бантинга дал мне достаточно подсказки, чтобы найти то, что мне нужно:
Так, например, в следующем фрагменте кода:
myInstance.constructor.name
вернется"MyObject"
.источник
function getType(o) { return o && o.constructor && o.constructor.name }
Небольшой трюк, который я использую:
источник
class Square
, названиеSquare.name
/MySquare.constructor.name
вместоSquare.prototype.name
; добавивname
функцию конструктора, она не загрязняет прототип или любой другой экземпляр, но доступна из любого.Обновить
Чтобы быть точным, я думаю, что OP попросил функцию, которая получает имя конструктора для конкретного объекта. С точки зрения Javascript,
object
не имеет типа, но является типом и сам по себе . Однако разные объекты могут иметь разные конструкторы .Примечание: приведенный ниже пример устарел.
Сообщение в блоге связаны христианской Шиберрас содержит хороший пример того , как сделать это. А именно, расширяя прототип Object:
источник
test.getClassName()
противgetClassName.apply(test)
.Использование Object.prototype.toString
Оказывается, что в этом сообщении вы можете использовать Object.prototype.toString - низкоуровневую и универсальную реализацию toString - чтобы получить тип для всех встроенных типов.
Можно написать короткую вспомогательную функцию, такую как
источник
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Вот решение, которое я придумала, которое решает недостатки instanceof. Он может проверять типы объектов из кросс-окон и кросс-фреймов и не имеет проблем с примитивными типами.
Для isInstance требуются два параметра: объект и тип. Реальная хитрость в том, как это работает, состоит в том, что он проверяет, находится ли объект из того же окна, и если нет, получает окно объекта.
Примеры:
Аргумент типа также может быть функцией обратного вызова, которая возвращает конструктор. Функция обратного вызова получит один параметр, который является окном предоставленного объекта.
Примеры:
Следует иметь в виду, что IE <9 не предоставляет конструктор для всех объектов, поэтому вышеприведенный тест для NodeList вернул бы false, а также isInstance (alert, "Function") вернул бы false.
источник
Я на самом деле искал похожую вещь и наткнулся на этот вопрос. Вот как я получаю типы: jsfiddle
источник
Вы должны использовать
somevar.constructor.name
как:источник
Используйте,
constructor.name
когда можете, и регулярные выражения, когда я не могу.источник
Функция kind () из Agave.JS вернет:
Он работает со всеми объектами и примитивами JS, независимо от того, как они были созданы. , и не вызывает никаких сюрпризов. Примеры:
чисел
NaN
Струны
Булевы
Массивы
Объекты
Даты
функции
не определено
значение NULL
источник
Вы можете использовать
instanceof
оператор, чтобы увидеть, является ли объект экземпляром другого, но поскольку классов нет, вы не можете получить имя класса.источник
instanceof
только проверяет, наследуется ли объект от других объектов. Например, простое[]
наследует от Array, но Array также наследует от Object. Поскольку большинство объектов имеют несколько уровней наследования, поиск ближайшего прототипа - лучший метод. Смотри мой ответ как.Вот реализация, основанная на принятом ответе :
Мы используем свойство конструктора только тогда, когда у нас нет другого выбора.
источник
Вы можете использовать оператор instanceof, чтобы определить, является ли объект экземпляром определенного класса или нет. Если вы не знаете имя типа объекта, вы можете использовать его свойство конструктора. Свойство constructor объектов, является ссылкой на функцию, которая используется для их инициализации. Пример:
Теперь c1.constructor является ссылкой на
Circle()
функцию. Вы также можете использоватьtypeof
оператора, ноtypeof
оператор показывает ограниченную информацию. Одним из решений является использованиеtoString()
метода глобального объекта Object. Например, если у вас есть объект, скажем, myObject, вы можете использоватьtoString()
метод глобального объекта для определения типа класса myObject. Использовать этот:источник
Скажи у тебя есть
var obj;
Если вам просто нужно имя типа obj, например «Объект», «Массив» или «Строка», вы можете использовать это:
источник
Самое близкое, что вы можете получить
typeof
, но он возвращает «объект» только для любого типа пользовательского типа. Для тех, см. Джейсон Бантинг .Отредактируйте, Джейсон почему-то удалил свой пост, поэтому просто используйте
constructor
свойство объекта.источник
Если кто-то искал решение, которое работает с jQuery, вот откорректированный вики-код (оригинал ломает jQuery).
источник
getName
и падает.В Lodash есть много isMethods, поэтому, если вы используете Lodash, может быть полезен подобный миксин:
Он добавляет в lodash метод с именем «identifier», который работает следующим образом:
Плункер: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
источник
Ладно, ребята, я уже несколько лет медленно разрабатываю метод «поймай все» для этого, лол! Хитрость заключается в том, чтобы:
Для примера (или чтобы посмотреть, как я справился с проблемой), посмотрите следующий код на github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js и найдите:
classOf =
,classOfIs =
и илиdefineSubClass =
(без обратных кавычек (`)).Как вы можете видеть, у меня есть некоторые механизмы, чтобы заставить
classOf
меня всегда давать имя типа классы / конструкторы независимо от того, является ли это примитивом, определяемым пользователем классом, значением, созданным с использованием собственного конструктора, Null, NaN и т. Д. Для каждого значения javascript я получу уникальное имя типа изclassOf
функции. Кроме того, я могу передать фактические конструкторы вsjl.classOfIs
чтобы проверить тип значения в дополнение к возможности передать его имя типа! Так, например:`` `// Пожалуйста, простите длинные пространства имен! Я понятия не имел о воздействии, пока не использовал их некоторое время (они сосут хаха)
`` `
Если вы хотите узнать больше о том, как я использую настройки, упомянутые выше, взгляните на репозиторий: https://github.com/elycruz/sjljs
Также книги с содержанием по теме: - «Шаблоны JavaScript» Стояна Стефанова. - «Javascript - Полное руководство». Дэвид Фланаган. - и многие другие .. (поиск в сети).
Также вы можете быстро протестировать функции, о которых я говорю, здесь: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (также путь 0.5.18 в URL содержит источники из github там минус node_modules и тому подобное).
Удачного кодирования!
источник
Довольно простой!
источник
Использование
class.name
. Это также работает сfunction.name
.источник
class
а не экземпляр.