Gibt es eine JavaScript - Äquivalent von Java ‚s class.getName()
?
javascript
Ewen Cartwright
quelle
quelle
Antworten:
Nein .
ES2015 Update : Der Name
class Foo {}
istFoo.name
. Der Name derthing
Klassething
lautet unabhängig vom Typthing.constructor.name
. Eingebaute Konstruktoren in einer ES2015-Umgebung haben die richtigename
Eigenschaft. zum Beispiel(2).constructor.name
ist"Number"
.Aber hier sind verschiedene Hacks, die alle auf die eine oder andere Weise herunterfallen:
Hier ist ein Hack, der das tut, was Sie brauchen - seien Sie sich bewusst, dass er den Prototyp des Objekts modifiziert, etwas, das die Leute missbilligen (normalerweise aus gutem Grund).
Jetzt haben alle Ihre Objekte die Funktion,
getName()
die den Namen des Konstruktors als Zeichenfolge zurückgibt. Ich habe dies in getestetFF3
undIE7
kann nicht für andere Implementierungen sprechen.Wenn Sie dies nicht möchten, finden Sie hier eine Diskussion über die verschiedenen Möglichkeiten zur Bestimmung von Typen in JavaScript ...
Ich habe dies kürzlich aktualisiert, um es etwas ausführlicher zu gestalten, obwohl es kaum so ist. Korrekturen willkommen ...
Nutzung der
constructor
Eigenschaft ...Jeder
object
hat einen Wert für seineconstructor
Eigenschaft, aber je nachdem, wie dieser erstelltobject
wurde und was Sie mit diesem Wert tun möchten, kann er nützlich sein oder auch nicht.Im Allgemeinen können Sie die
constructor
Eigenschaft verwenden, um den Typ des Objekts wie folgt zu testen:Das funktioniert also gut genug für die meisten Bedürfnisse. Das gesagt...
Vorsichtsmaßnahmen
Wird nicht funktionieren AT ALL in vielen Fällen
Dieses Muster ist zwar gebrochen, aber weit verbreitet:
Objects
Konstruiert übernew Thingy
wird eineconstructor
Eigenschaft haben, die zeigtObject
, nichtThingy
. Wir fallen also gleich zu Beginn; Sie können einfach nichtconstructor
auf eine Codebasis vertrauen , die Sie nicht kontrollieren.Mehrfachvererbung
Ein Beispiel, bei dem dies nicht so offensichtlich ist, ist die Verwendung der Mehrfachvererbung:
Die Dinge funktionieren jetzt nicht so, wie Sie es vielleicht erwarten:
Daher erhalten Sie möglicherweise unerwartete Ergebnisse, wenn für
object
Ihre Tests ein andererobject
Satz als der für Sie festgelegt wurdeprototype
. Es gibt Möglichkeiten, dies außerhalb des Rahmens dieser Diskussion zu umgehen.Es gibt andere Verwendungszwecke für das
constructor
Eigentum, einige davon interessant, andere weniger; Im Moment werden wir uns nicht mit diesen Verwendungen befassen, da sie für diese Diskussion nicht relevant sind.Funktioniert nicht über Rahmen und Fenster hinweg
Die Verwendung
.constructor
für die Typprüfung wird unterbrochen, wenn Sie den Typ von Objekten überprüfen möchten, die von verschiedenenwindow
Objekten stammen, z. B. von einem Iframe oder einem Popup-Fenster. Dies liegt daran, dass esconstructor
in jedem "Fenster" eine andere Version jedes Kerntyps gibt, d. H.Verwenden des
instanceof
Operators ...Der
instanceof
Bediener ist ebenfalls eine saubere Methode zum Testen desobject
Typs, hat jedoch genau wie dieconstructor
Eigenschaft seine eigenen potenziellen Probleme .Funktioniert aber
instanceof
nicht für wörtliche Werte (weil Literale dies nicht sindObjects
)Die Literale müssen zum Beispiel in ein eingewickelt
Object
werden, damitinstanceof
sie funktionierenDie
.constructor
Prüfung funktioniert gut für Literale, da der.
Methodenaufruf die Literale implizit in ihren jeweiligen Objekttyp einschließtWarum zwei Punkte für die 3? Weil Javascript den ersten Punkt als Dezimalpunkt interpretiert;)
Funktioniert nicht über Rahmen und Fenster hinweg
instanceof
funktioniert auch nicht über verschiedene Fenster hinweg, aus dem gleichen Grund wie dieconstructor
Eigenschaftsprüfung.Nutzung der
name
Eigenschaft derconstructor
Eigenschaft ...Funktioniert nicht AT ALL in vielen Fällen
Wieder siehe oben; Es ist durchaus üblich
constructor
, völlig falsch und nutzlos zu sein.Funktioniert NICHT in <IE9
Mit using erhalten
myObjectInstance.constructor.name
Sie eine Zeichenfolge, die den Namen der verwendetenconstructor
Funktion enthält, jedoch denconstructor
zuvor erwähnten Einschränkungen bezüglich der Eigenschaft unterliegt .Für IE9 und höher können Sie Affen-Patches zur Unterstützung verwenden :
Aktualisierte Version des betreffenden Artikels. Dies wurde 3 Monate nach Veröffentlichung des Artikels hinzugefügt. Dies ist die empfohlene Version, die vom Autor des Artikels, Matthew Scharley, verwendet wird. Diese Änderung wurde durch Kommentare inspiriert, die auf mögliche Fallstricke im vorherigen Code hinweisen .
Verwenden von Object.prototype.toString
Es stellt sich heraus, dass Sie, wie in diesem Beitrag beschrieben ,
Object.prototype.toString
die einfache und generische Implementierung von verwenden könnentoString
, um den Typ für alle integrierten Typen abzurufenMan könnte eine kurze Hilfsfunktion wie schreiben
um die Kruft zu entfernen und nur den Typnamen zu erhalten
Es wird jedoch
Object
für alle benutzerdefinierten Typen zurückgegeben.Vorsichtsmaßnahmen für alle ...
All dies unterliegt einem potenziellen Problem, und das ist die Frage, wie das betreffende Objekt konstruiert wurde. Hier sind verschiedene Möglichkeiten zum Erstellen von Objekten und die Werte, die die verschiedenen Methoden der Typprüfung zurückgeben:
Obwohl in diesen Beispielen nicht alle Permutationen vorhanden sind, gibt es hoffentlich genug, um Ihnen eine Vorstellung davon zu geben, wie chaotisch die Dinge je nach Ihren Anforderungen werden können. Nehmen Sie nichts an. Wenn Sie nicht genau verstehen, wonach Sie suchen, kann es sein, dass Sie Code brechen, wo Sie dies nicht erwarten, weil Sie die Feinheiten nicht verstehen.
HINWEIS:
Die Diskussion des
typeof
Operators mag als eklatante Auslassung erscheinen, ist jedoch nicht hilfreich, um festzustellen, obobject
es sich um einen bestimmten Typ handelt, da dies sehr einfach ist. Estypeof
ist wichtig zu verstehen, wo es nützlich ist, aber ich glaube derzeit nicht, dass es für diese Diskussion schrecklich relevant ist. Mein Geist ist jedoch offen für Veränderungen. :) :)quelle
constructor
Methode des Objekts (entweder mit.toString()
oder.name
) untersuchen, nicht funktionieren, wenn Ihr Javascript mit einem Tool wie uglify oder der Rails-Asset-Pipeline minimiert wurde. Durch die Minimierung wird der Konstruktor umbenannt, sodass Sie falsche Klassennamen wie erhaltenn
. Wenn Sie sich in diesem Szenario befinden, möchten Sie möglicherweise nur manuell eineclassName
Eigenschaft für Ihre Objekte definieren und diese stattdessen verwenden.Die Antwort von Jason Bunting gab mir genug Anhaltspunkte, um herauszufinden, was ich brauchte:
So zum Beispiel im folgenden Code:
myInstance.constructor.name
würde zurückkehren"MyObject"
.quelle
function getType(o) { return o && o.constructor && o.constructor.name }
Ein kleiner Trick, den ich benutze:
quelle
class Square
, lautet der NameSquare.name
/MySquare.constructor.name
stattSquare.prototype.name
; Durch Aktivierenname
der Konstruktorfunktion wird der Prototyp oder eine Instanz nicht verschmutzt, sondern kann von beiden aus aufgerufen werden.Aktualisieren
Um genau zu sein, hat OP nach einer Funktion gefragt, die den Konstruktornamen für ein bestimmtes Objekt abruft. In Bezug auf Javascript hat
object
es keinen Typ, sondern ist ein Typ von und für sich . Unterschiedliche Objekte können jedoch unterschiedliche Konstruktoren haben .Hinweis: Das folgende Beispiel ist veraltet.
Ein von Christian Sciberras verlinkter Blog-Beitrag enthält ein gutes Beispiel dafür. Durch Erweitern des Objektprototyps:
quelle
test.getClassName()
vsgetClassName.apply(test)
.Verwenden von Object.prototype.toString
Wie in diesem Beitrag beschrieben, können Sie Object.prototype.toString - die einfache und generische Implementierung von toString - verwenden, um den Typ für alle integrierten Typen abzurufen
Man könnte eine kurze Hilfsfunktion wie schreiben
quelle
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Hier ist eine Lösung, die ich gefunden habe und die die Mängel von instanceof behebt. Es kann die Typen eines Objekts anhand von Fenstern und Rahmen überprüfen und hat keine Probleme mit primitiven Typen.
isInstance erfordert zwei Parameter: ein Objekt und einen Typ. Der eigentliche Trick bei der Funktionsweise besteht darin, zu überprüfen, ob das Objekt aus demselben Fenster stammt und ob das Objektfenster nicht abgerufen wird.
Beispiele:
Das Typargument kann auch eine Rückruffunktion sein, die einen Konstruktor zurückgibt. Die Rückruffunktion erhält einen Parameter, der das Fenster des bereitgestellten Objekts ist.
Beispiele:
Beachten Sie, dass IE <9 den Konstruktor nicht für alle Objekte bereitstellt, sodass der obige Test für NodeList false zurückgibt und auch eine isInstance (Warnung, "Funktion") false zurückgibt.
quelle
Ich suchte tatsächlich nach einer ähnlichen Sache und stieß auf diese Frage. So bekomme ich Typen: jsfiddle
quelle
Sie sollten
somevar.constructor.name
wie folgt verwenden :quelle
Verwenden
constructor.name
Sie, wenn Sie können, und Regex-Funktion, wenn ich nicht kann.quelle
Die Funktion kind () von Agave.JS gibt Folgendes zurück:
Es funktioniert mit allen JS-Objekten und Grundelementen, unabhängig davon, wie sie erstellt wurden , und bietet keine Überraschungen. Beispiele:
Zahlen
NaN
Saiten
Boolesche Werte
Arrays
Objekte
Termine
Funktionen
nicht definiert
Null
quelle
Sie können den
instanceof
Operator verwenden, um festzustellen, ob ein Objekt eine Instanz eines anderen ist. Da jedoch keine Klassen vorhanden sind, können Sie keinen Klassennamen abrufen.quelle
instanceof
prüft aber nur, ob ein Objekt von einem anderen Objekt erbt. ZB[]
erbt ein einfaches von Array, aber Array erbt auch von Object. Da die meisten Objekte mehrere Vererbungsebenen haben, ist es besser , den nächstgelegenen Prototyp zu finden . Siehe meine Antwort für wie.Hier ist eine Implementierung basierend auf der akzeptierten Antwort :
Wir verwenden die Konstruktoreigenschaft nur, wenn wir keine andere Wahl haben.
quelle
Mit dem Operator "instanceof" können Sie bestimmen, ob ein Objekt eine Instanz einer bestimmten Klasse ist oder nicht. Wenn Sie den Namen des Objekttyps nicht kennen, können Sie dessen Konstruktoreigenschaft verwenden. Die Konstruktoreigenschaft von Objekten ist ein Verweis auf die Funktion, mit der sie initialisiert werden. Beispiel:
Jetzt ist c1.constructor eine Referenz auf die
Circle()
Funktion. Sie können dentypeof
Operator auch verwenden, dertypeof
Operator zeigt jedoch nur begrenzte Informationen an. Eine Lösung besteht darin, dietoString()
Methode des globalen Objektobjekts zu verwenden. Wenn Sie beispielsweise ein Objekt haben, z. B. myObject, können Sie dietoString()
Methode des globalen Objekts verwenden, um den Typ der Klasse von myObject zu bestimmen. Benutze das:quelle
Sagen Sie, Sie haben
var obj;
Wenn Sie nur den Namen des Typs von obj wie "Object", "Array" oder "String" möchten, können Sie Folgendes verwenden:
quelle
Der nächstgelegene Wert ist
typeof
, gibt jedoch nur "Objekt" für einen benutzerdefinierten Typ zurück. Für diese siehe Jason Bunting .Bearbeiten, Jason hat seinen Beitrag aus irgendeinem Grund gelöscht, verwenden Sie also einfach die
constructor
Eigenschaft von Object .quelle
Wenn jemand nach einer Lösung gesucht hat, die mit jQuery funktioniert, finden Sie hier den angepassten Wiki-Code (das Original bricht jQuery).
quelle
getName
und fällt um.Lodash hat viele isMethods. Wenn Sie also Lodash verwenden, kann ein Mixin wie dieses nützlich sein:
Es fügt eine Methode namens "Identifizieren" zu lodash hinzu, die wie folgt funktioniert:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
quelle
Ok, Leute, ich habe über einige Jahre langsam eine Catch-All-Methode dafür entwickelt, lol! Der Trick ist:
Ein Beispiel (oder um zu sehen, wie ich mit dem Problem umgegangen bin) finden Sie im folgenden Code auf github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js und suchen Sie nach:
classOf =
,classOfIs =
Und oderdefineSubClass =
(ohne die Backticks ( `)).Wie Sie sehen, sind einige Mechanismen vorhanden, um zu erzwingen
classOf
, dass ich immer den Namen des Klassen- / Konstruktortyps bekomme, unabhängig davon, ob es sich um ein Grundelement, eine benutzerdefinierte Klasse, einen Wert handelt, der mit einem nativen Konstruktor erstellt wurde, Null, NaN usw. Für jeden einzelnen Javascript-Wert erhalte ich seinen eindeutigen Typnamen von derclassOf
Funktion. Außerdem kann ich tatsächliche Konstruktoren übergebensjl.classOfIs
, um den Typ eines Werts zu überprüfen, und zusätzlich den Typnamen übergeben! Also zum Beispiel:`` `// Bitte vergib lange Namespaces! Ich hatte keine Ahnung von den Auswirkungen, bis ich sie für eine Weile benutzt habe (sie saugen haha)
`` `
Wenn Sie mehr darüber erfahren möchten, wie ich das oben erwähnte Setup verwende, schauen Sie sich das Repo an: https://github.com/elycruz/sjljs
Auch Bücher mit Inhalten zum Thema: - "JavaScript Patterns" von Stoyan Stefanov. - "Javascript - Der endgültige Leitfaden." von David Flanagan. - und viele andere .. (Suche im Web).
Sie können auch die Funktionen, über die ich hier spreche, schnell testen: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (auch der Pfad 0.5.18 in der URL enthält die Quellen von github dort abzüglich der node_modules und so).
Viel Spaß beim Codieren!
quelle
Ziemlich Einfach!
quelle
Verwenden Sie
class.name
. Dies funktioniert auch mitfunction.name
.quelle
class
und nicht Instanz.