Y at - il un JavaScript équivalent de Java de class.getName()
?
javascript
Ewen Cartwright
la source
la source
Réponses:
Non .
Mise à jour ES2015 : le nom de
class Foo {}
estFoo.name
. Le nom dething
la classe de, quel que soit sonthing
type, estthing.constructor.name
. Les constructeurs intégrés dans un environnement ES2015 ont laname
propriété correcte ; par exemple(2).constructor.name
est"Number"
.Mais voici différents hacks qui tombent tous d'une manière ou d'une autre:
Voici un hack qui fera ce dont vous avez besoin - sachez qu'il modifie le prototype de l'objet, quelque chose que les gens désapprouvent (généralement pour une bonne raison)
Maintenant, tous vos objets auront la fonction
getName()
,, qui renverra le nom du constructeur sous forme de chaîne. J'ai testé cela dansFF3
etIE7
je ne peux pas parler pour d'autres implémentations.Si vous ne voulez pas le faire, voici une discussion sur les différentes façons de déterminer les types en JavaScript ...
J'ai récemment mis à jour cela pour être un peu plus exhaustif, bien que ce ne soit pas ça. Les corrections sont les bienvenues ...
Utilisation de la
constructor
propriété ...Chacun
object
a une valeur pour saconstructor
propriété, mais selon la façon dont cela aobject
été construit ainsi que ce que vous voulez faire avec cette valeur, cela peut être utile ou non.De manière générale, vous pouvez utiliser la
constructor
propriété pour tester le type de l'objet comme ceci:Donc, cela fonctionne assez bien pour la plupart des besoins. Cela dit...
Avertissements
Ne fonctionnera pas du tout dans de nombreux cas
Ce schéma, bien que rompu, est assez courant:
Objects
construit vianew Thingy
aura uneconstructor
propriété qui pointe versObject
, nonThingy
. Nous tombons donc tout de suite au début; vous ne pouvez tout simplement pas faire confianceconstructor
à une base de code que vous ne contrôlez pas.Héritage multiple
Un exemple où ce n'est pas aussi évident utilise l'héritage multiple:
Les choses ne fonctionnent plus comme vous pouvez vous y attendre:
Ainsi, vous pourriez obtenir des résultats inattendus si
object
votre test a unobject
ensemble différentprototype
. Il existe des moyens de contourner cela en dehors du cadre de cette discussion.Il existe d'autres utilisations de la
constructor
propriété, certaines intéressantes, d'autres moins; pour l'instant, nous ne nous pencherons pas sur ces utilisations, car elles ne sont pas pertinentes pour cette discussion.Ne fonctionnera pas cross-frame et cross-window
L'utilisation
.constructor
de la vérification de type est interrompue lorsque vous souhaitez vérifier le type d'objets provenant d'window
objets différents , par exemple celui d'une iframe ou d'une fenêtre contextuelle. C'est parce qu'il y a une version différente de chaque type de noyauconstructor
dans chaque `fenêtre ', c'est-à-direUtilisation de l'
instanceof
opérateur ...L'
instanceof
opérateur est également un moyen propre de tester leobject
type, mais a ses propres problèmes potentiels, tout comme laconstructor
propriété.Mais
instanceof
ne fonctionne pas pour les valeurs littérales (car les littéraux ne le sont pasObjects
)Les littéraux doivent être enveloppés dans un
Object
pourinstanceof
fonctionner, par exempleLa
.constructor
vérification fonctionne correctement pour les littéraux car l'.
invocation de méthode enveloppe implicitement les littéraux dans leur type d'objet respectifPourquoi deux points pour les 3? Parce que Javascript interprète le premier point comme un point décimal;)
Ne fonctionnera pas cross-frame et cross-window
instanceof
ne fonctionnera pas non plus sur différentes fenêtres, pour la même raison que laconstructor
vérification des propriétés.Utilisation de la
name
propriété de laconstructor
propriété ...Ne fonctionne pas du tout dans de nombreux cas
Encore une fois, voir ci-dessus; il est assez courant
constructor
d'être complètement et complètement faux et inutile.Ne fonctionne pas dans <IE9
L'utilisation
myObjectInstance.constructor.name
vous donnera une chaîne contenant le nom de laconstructor
fonction utilisée, mais est soumise aux avertissements concernant laconstructor
propriété qui ont été mentionnés précédemment.Pour IE9 et versions ultérieures, vous pouvez utiliser le patch monkey pour prendre en charge :
Version mise à jour de l'article en question. Cela a été ajouté 3 mois après la publication de l'article, c'est la version recommandée à utiliser par l'auteur de l'article Matthew Scharley. Ce changement a été inspiré par des commentaires soulignant les pièges potentiels dans le code précédent.
Utilisation d'Object.prototype.toString
Il s'avère que, comme ce post le détaille , vous pouvez utiliser
Object.prototype.toString
- le bas niveau et l'implémentation générique detoString
- pour obtenir le type pour tous les types intégrésOn pourrait écrire une fonction d'aide courte telle que
pour supprimer la loupe et obtenir juste le nom du type
Cependant, il reviendra
Object
pour tous les types définis par l'utilisateur.Des mises en garde pour tous ...
Tous ces éléments sont sujets à un problème potentiel, et c'est la question de savoir comment l'objet en question a été construit. Voici différentes façons de créer des objets et les valeurs que les différentes méthodes de vérification de type renverront:
Bien que toutes les permutations ne soient pas présentes dans cet ensemble d'exemples, j'espère qu'il y en a assez pour vous donner une idée de la façon dont les choses peuvent devenir désordonnées en fonction de vos besoins. Ne présumez rien, si vous ne comprenez pas exactement ce que vous recherchez, vous pouvez vous retrouver avec une rupture de code là où vous ne vous y attendez pas en raison d'un manque de grokking des subtilités.
REMARQUE:
La discussion de l'
typeof
opérateur peut sembler être une omission flagrante, mais elle n'est vraiment pas utile pour aider à identifier si anobject
est un type donné, car elle est très simpliste. Iltypeof
est important de comprendre où est utile, mais je ne pense pas que cela soit vraiment pertinent pour cette discussion. Mais mon esprit est ouvert au changement. :)la source
constructor
méthode de l'objet (avec.toString()
ou.name
) ne fonctionneront pas si votre Javascript a été minifié avec un outil comme uglify ou le pipeline d'actifs Rails. La minification renomme le constructeur, vous vous retrouverez donc avec des noms de classe incorrects commen
. Si vous êtes dans ce scénario, vous pouvez simplement définir manuellement uneclassName
propriété sur vos objets et l'utiliser à la place.La réponse de Jason Bunting m'a donné suffisamment d'indices pour trouver ce dont j'avais besoin:
Ainsi, par exemple, dans le morceau de code suivant:
myInstance.constructor.name
reviendrait"MyObject"
.la source
function getType(o) { return o && o.constructor && o.constructor.name }
Un petit truc que j'utilise:
la source
class Square
, le nom estSquare.name
/MySquare.constructor.name
plutôt queSquare.prototype.name
; en activantname
la fonction constructeur, il ne pollue ni le prototype ni aucune instance, mais il est accessible depuis l'un ou l'autre.Mise à jour
Pour être précis, je pense que OP a demandé une fonction qui récupère le nom du constructeur pour un objet particulier. En termes de Javascript,
object
n'a pas de type mais est un type de et en soi . Cependant, différents objets peuvent avoir différents constructeurs .Remarque: l'exemple ci-dessous est obsolète.
Un article de blog lié par Christian Sciberras contient un bon exemple sur la façon de le faire. A savoir, en étendant le prototype Object:
la source
test.getClassName()
vsgetClassName.apply(test)
.Utilisation d'Object.prototype.toString
Il s'avère que, comme ce post le détaille, vous pouvez utiliser Object.prototype.toString - l'implémentation générique de bas niveau de toString - pour obtenir le type pour tous les types intégrés
On pourrait écrire une fonction d'aide courte telle que
la source
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Voici une solution que j'ai trouvée qui résout les lacunes d'instanceof. Il peut vérifier les types d'objets à partir de fenêtres croisées et de cadres croisés et n'a pas de problèmes avec les types primitifs.
isInstance nécessite deux paramètres: un objet et un type. La véritable astuce pour savoir comment cela fonctionne est qu'il vérifie si l'objet provient de la même fenêtre et s'il n'obtient pas la fenêtre de l'objet.
Exemples:
L'argument type peut également être une fonction de rappel qui renvoie un constructeur. La fonction de rappel recevra un paramètre qui est la fenêtre de l'objet fourni.
Exemples:
Une chose à garder à l'esprit est que IE <9 ne fournit pas le constructeur sur tous les objets, donc le test ci-dessus pour NodeList retournerait faux et aussi une isInstance (alerte, "Fonction") retournerait faux.
la source
Je cherchais en fait une chose similaire et suis tombé sur cette question. Voici comment j'obtiens des types: jsfiddle
la source
Vous devez utiliser
somevar.constructor.name
comme:la source
À utiliser
constructor.name
quand vous le pouvez et à fonctionner régulièrement lorsque je ne peux pas.la source
La fonction kind () d' Agave.JS renverra:
Il fonctionne sur tous les objets et primitives JS, quelle que soit la façon dont ils ont été créés , et n'a aucune surprise. Exemples:
Nombres
NaN
Cordes
Booléens
Tableaux
Objets
Rendez-vous
Les fonctions
indéfini
nul
la source
Vous pouvez utiliser l'
instanceof
opérateur pour voir si un objet est une instance d'un autre, mais comme il n'y a pas de classes, vous ne pouvez pas obtenir de nom de classe.la source
instanceof
vérifie simplement si un objet hérite d'un autre objet. Par exemple, un simple[]
hérite d'Array, mais Array hérite également d'Object. Comme la plupart des objets ont plusieurs niveaux d'héritage, trouver le prototype le plus proche est une meilleure technique. Voir ma réponse pour savoir comment.Voici une implémentation basée sur la réponse acceptée :
Nous n'utilisons la propriété constructeur que lorsque nous n'avons pas d'autre choix.
la source
Vous pouvez utiliser l'opérateur "instanceof" pour déterminer si un objet est une instance d'une certaine classe ou non. Si vous ne connaissez pas le nom du type d'un objet, vous pouvez utiliser sa propriété constructeur. La propriété constructeur des objets est une référence à la fonction utilisée pour les initialiser. Exemple:
Maintenant c1.constructor est une référence à la
Circle()
fonction. Vous pouvez également utiliser l'typeof
opérateur, mais l'typeof
opérateur affiche des informations limitées. Une solution consiste à utiliser latoString()
méthode de l'objet global Object. Par exemple, si vous avez un objet, par exemple myObject, vous pouvez utiliser latoString()
méthode de l'objet global pour déterminer le type de la classe de myObject. Utilisez ceci:la source
Dis que tu as
var obj;
Si vous voulez juste le nom du type d'obj, comme "Object", "Array" ou "String", vous pouvez utiliser ceci:
la source
Le plus proche que vous pouvez obtenir est
typeof
, mais il ne renvoie que "objet" pour tout type de type personnalisé. Pour ceux-ci, voir Jason Bunting .Modifier, Jason a supprimé son message pour une raison quelconque, alors utilisez simplement la
constructor
propriété Object .la source
Si quelqu'un cherchait une solution qui fonctionne avec jQuery, voici le code wiki ajusté (l'original brise jQuery).
la source
getName
et tombe.Lodash a de nombreux isMethods, donc si vous utilisez Lodash, un mixage comme celui-ci peut être utile:
Il ajoute une méthode à lodash appelée "identifier" qui fonctionne comme suit:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
la source
Ok, les gens, je construis lentement une méthode fourre-tout pour cela depuis quelques années lol! L'astuce consiste à:
Pour un exemple (ou pour voir comment j'ai résolu le problème), regardez le code suivant sur github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js et recherchez:
classOf =
,classOfIs =
, Et oudefineSubClass =
(sans les guillemets obliques ( `)).Comme vous pouvez le voir, j'ai quelques mécanismes en place pour forcer
classOf
à toujours me donner le nom du type classes / constructors, qu'il s'agisse d'une primitive, d'une classe définie par l'utilisateur, d'une valeur créée à l'aide d'un constructeur natif, Null, NaN, etc. Pour chaque valeur javascript unique, je vais obtenir son nom de type unique de laclassOf
fonction. De plus, je peux passer dans des constructeurs réelssjl.classOfIs
pour vérifier le type d'une valeur en plus de pouvoir également passer son nom de type! Ainsi, par exemple:`` `// Veuillez pardonner les longs espaces de noms! Je n'avais aucune idée de l'impact qu'après les avoir utilisés pendant un certain temps (ils sucent haha)
`` ''
Si vous souhaitez en savoir plus sur la façon dont j'utilise la configuration mentionnée ci-dessus, jetez un œil au dépôt: https://github.com/elycruz/sjljs
Également des livres avec du contenu sur le sujet: - "JavaScript Patterns" par Stoyan Stefanov. - "Javascript - Le guide définitif." par David Flanagan. - et bien d'autres .. (recherche sur le web).
Vous pouvez également tester rapidement les fonctionnalités dont je parle ici: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (également le chemin 0.5.18 dans l'url a les sources de github là-bas moins les node_modules et autres).
Codage heureux!
la source
Assez simple!
la source
Utilisez
class.name
. Cela fonctionne également avecfunction.name
.la source
class
et non l'instance.