Czy istnieje javascript równoważne Javy s” class.getName()
?
javascript
Ewen Cartwright
źródło
źródło
Odpowiedzi:
Nie .
Aktualizacja ES2015 : nazwa
class Foo {}
toFoo.name
. Nazwathing
klasy, niezależnie odthing
typu, tothing.constructor.name
. Wbudowane konstruktory w środowisku ES2015 mają poprawnąname
właściwość; na przykład(2).constructor.name
jest"Number"
.Ale oto różne hacki, które wszystkie upadają w ten czy inny sposób:
Oto hack, który zrobi to, czego potrzebujesz - pamiętaj, że modyfikuje prototyp obiektu, coś, na co ludzie patrzą z niechęcią (zwykle z dobrego powodu)
Teraz wszystkie twoje obiekty będą miały funkcję
getName()
, która zwróci nazwę konstruktora jako ciąg znaków. Przetestowałem toFF3
iIE7
nie mogę mówić o innych implementacjach.Jeśli nie chcesz tego robić, oto dyskusja na temat różnych sposobów określania typów w JavaScript ...
Niedawno zaktualizowałem to, aby było nieco bardziej wyczerpujące, chociaż nie jest to wcale takie trudne. Mile widziane poprawki ...
Korzystanie z
constructor
właściwości ...Każda
object
ma wartość dla swojejconstructor
właściwości, ale w zależności od tego, jakobject
została skonstruowana, a także od tego, co chcesz zrobić z tą wartością, może to być przydatne lub nie.Ogólnie rzecz biorąc, możesz użyć
constructor
właściwości do przetestowania typu obiektu w następujący sposób:To działa wystarczająco dobrze dla większości potrzeb. To mówi...
Ostrzeżenia
W wielu przypadkach nie będzie działać WSZYSTKO
Ten wzór, choć zepsuty, jest dość powszechny:
Objects
zbudowany za pośrednictwemnew Thingy
będzie miałconstructor
właściwość, która wskazujeObject
, a nieThingy
. Więc upadamy od samego początku; po prostu nie możesz zaufaćconstructor
bazie kodu, której nie kontrolujesz.Wielokrotne dziedziczenie
Przykładem, w którym nie jest to tak oczywiste, jest wielokrotne dziedziczenie:
Rzeczy nie działają teraz, jak można się spodziewać:
Możesz więc otrzymać nieoczekiwane wyniki, jeśli
object
twoje testy mają innyobject
zestawprototype
. Istnieją na to sposoby poza zakresem tej dyskusji.Istnieją inne zastosowania
constructor
nieruchomości, niektóre interesujące, inne nie tak bardzo; na razie nie zagłębimy się w te zastosowania, ponieważ nie ma to znaczenia w tej dyskusji.Nie działa cross-frame i cross-window
Używanie
.constructor
do sprawdzania typu zepsuje się, gdy chcesz sprawdzić typ obiektów pochodzących z różnychwindow
obiektów, np. Iframe lub wyskakującego okna. Wynika to z faktu, żeconstructor
w każdym „oknie” jest inna wersja każdego typu rdzenia , tjKorzystanie z
instanceof
operatora ...instanceof
Operator jest czysty sposób testowaniaobject
typu, jak również, ale ma swoje potencjalne problemy, podobnie jakconstructor
nieruchomości.Ale
instanceof
nie działa dla wartości literalnych (ponieważ literały nie sąObjects
)Literały muszą być owinięte np.
Object
W celuinstanceof
pracy.constructor
Check działa dobrze dla literałów, ponieważ.
wywołania metody niejawnie zawija literały w ich odpowiedniego typu obiektuDlaczego dwie kropki na 3? Ponieważ Javascript interpretuje pierwszą kropkę jako przecinek dziesiętny;)
Nie działa cross-frame i cross-window
instanceof
również nie będzie działać w różnych oknach z tego samego powodu, coconstructor
sprawdzenie właściwości.Korzystanie z
name
właściwościconstructor
nieruchomości ...Nie działa w ogóle w wielu przypadkach
Ponownie, patrz wyżej; dość powszechne jest
constructor
to, że jest całkowicie i całkowicie błędne i bezużyteczne.NIE działa w <IE9
Użycie
myObjectInstance.constructor.name
da ci ciąg zawierający nazwęconstructor
użytej funkcji, ale podlega zastrzeżeniom dotyczącymconstructor
wcześniej wspomnianej właściwości.W IE9 i nowszych wersjach możesz wesprzeć małpą łatkę :
Zaktualizowana wersja z tego artykułu. Zostało to dodane 3 miesiące po opublikowaniu artykułu, jest to zalecana wersja do użycia przez autora artykułu Matthew Scharley. Ta zmiana została zainspirowana komentarzami wskazującymi potencjalne pułapki w poprzednim kodzie.
Korzystanie z Object.prototype.toString
Okazuje się, że jako szczegóły tego postu możesz użyć
Object.prototype.toString
- niskiego poziomu i ogólnej implementacjitoString
- aby uzyskać typ dla wszystkich wbudowanych typówMożna napisać krótką funkcję pomocniczą, taką jak
aby usunąć cruft i uzyskać tylko nazwę typu
Zwróci jednak
Object
wszystkie typy zdefiniowane przez użytkownika.Ostrzeżenia dla wszystkich ...
Wszystkie z nich wiążą się z jednym potencjalnym problemem, a mianowicie z tym, jak skonstruowano przedmiotowy obiekt. Oto różne sposoby budowania obiektów i wartości, które zwrócą różne metody sprawdzania typu:
Chociaż nie wszystkie permutacje są obecne w tym zestawie przykładów, mam nadzieję, że wystarczy, aby dać ci wyobrażenie o tym, jak bałagan może się stać w zależności od twoich potrzeb. Nie zakładaj niczego, jeśli nie rozumiesz dokładnie, czego szukasz, możesz skończyć na łamaniu kodu tam, gdzie się tego nie spodziewasz, z powodu braku podejrzeń o subtelności.
UWAGA:
Dyskusja na temat
typeof
operatora może wydawać się rażącym pominięciem, ale tak naprawdę nie jest przydatna w pomaganiu w określeniu, czyobject
dany typ jest dany, ponieważ jest bardzo uproszczony. Zrozumienie, gdzietypeof
jest przydatny, jest ważne, ale obecnie nie uważam, aby miało to ogromne znaczenie w tej dyskusji. Mój umysł jest jednak otwarty na zmiany. :)źródło
constructor
metodę obiektu (za pomocą.toString()
lub.name
) nie będą działać, jeśli JavaScript został zminimalizowany za pomocą narzędzia takiego jak uglify lub potoku zasobów Rails. Minification zmienia nazwę konstruktora, więc skończysz z niepoprawnymi nazwami klas, takimi jakn
. Jeśli jesteś w tym scenariuszu, możesz po prostu ręcznie zdefiniowaćclassName
właściwość na swoich obiektach i użyć jej zamiast tego.Odpowiedź Jasona Buntinga dostarczyła mi wystarczającej wskazówki, by znaleźć to, czego potrzebowałem:
Na przykład w następującym fragmencie kodu:
myInstance.constructor.name
wróciłby"MyObject"
.źródło
function getType(o) { return o && o.constructor && o.constructor.name }
Mała sztuczka, której używam:
źródło
class Square
, nazwa toSquare.name
/MySquare.constructor.name
raczej niżSquare.prototype.name
; włączeniename
funkcji konstruktora nie zanieczyszcza prototypu ani żadnej instancji, ale jest dostępne z dowolnego z nich.Aktualizacja
Mówiąc ściślej, myślę, że OP poprosił o funkcję, która pobiera nazwę konstruktora dla określonego obiektu. Pod względem Javascript
object
nie ma typu, ale jest rodzajem samego w sobie . Jednak różne obiekty mogą mieć różne konstruktory .Uwaga: poniższy przykład jest przestarzały.
Wpis na blogu, do którego prowadzi Christian Sciberras, zawiera dobry przykład tego, jak to zrobić. Mianowicie poprzez rozszerzenie prototypu Object:
źródło
test.getClassName()
vsgetClassName.apply(test)
.Korzystanie z Object.prototype.toString
Okazuje się, że jako szczegóły tego postu możesz użyć Object.prototype.toString - niskiego poziomu i ogólnej implementacji toString - aby uzyskać typ dla wszystkich wbudowanych typów
Można napisać krótką funkcję pomocniczą, taką jak
źródło
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Oto rozwiązanie, które wymyśliłem, które rozwiązuje niedociągnięcia instancji. Może sprawdzać typy obiektów z okien krzyżowych i ramek krzyżowych i nie ma problemów z typami pierwotnymi.
isInstance wymaga dwóch parametrów: obiektu i typu. Prawdziwą sztuczką w jego działaniu jest to, że sprawdza, czy obiekt pochodzi z tego samego okna, a jeśli nie, pobiera okno obiektu.
Przykłady:
Argument typu może być także funkcją zwrotną, która zwraca konstruktor. Funkcja zwrotna otrzyma jeden parametr, którym jest okno podanego obiektu.
Przykłady:
Należy pamiętać, że IE <9 nie zapewnia konstruktora dla wszystkich obiektów, więc powyższy test dla NodeList zwróci false, a także isInstance (alert, „Funkcja”) zwróci false.
źródło
Tak naprawdę szukałem podobnej rzeczy i natknąłem się na to pytanie. Oto jak otrzymuję typy: jsfiddle
źródło
Powinieneś używać
somevar.constructor.name
jak:źródło
Użyj,
constructor.name
kiedy możesz, i regex, gdy nie mogę.źródło
Funkcja kind () z Agave.JS zwróci:
Działa na wszystkich obiektach i prymitywach JS, niezależnie od tego, jak zostały utworzone , i nie ma żadnych niespodzianek. Przykłady:
Liczby
NaN
Smyczki
Booleany
Tablice
Obiekty
Daktyle
Funkcje
nieokreślony
zero
źródło
Za pomocą
instanceof
operatora można sprawdzić, czy obiekt jest instancją innego obiektu, ale ponieważ nie ma klas, nie można uzyskać nazwy klasy.źródło
instanceof
sprawdza tylko, czy obiekt dziedziczy po innych obiektach. Np. Prosty[]
dziedziczy po Array, ale Array dziedziczy również po Object. Ponieważ większość obiektów ma wiele poziomów dziedziczenia, znalezienie najbliższego prototypu jest lepszą techniką. Zobacz moją odpowiedź, jak to zrobić.Oto implementacja oparta na zaakceptowanej odpowiedzi :
Używamy właściwości konstruktora tylko wtedy, gdy nie mamy innego wyboru.
źródło
Za pomocą operatora „instanceof” można ustalić, czy obiekt jest instancją określonej klasy, czy nie. Jeśli nie znasz nazwy typu obiektu, możesz użyć jego właściwości konstruktora. Właściwość konstruktora obiektów, jest odwołaniem do funkcji, która jest używana do ich inicjowania. Przykład:
Teraz c1.constructor jest odwołaniem do
Circle()
funkcji. Możesz także użyćtypeof
operatora, aletypeof
operator pokazuje ograniczone informacje. Jednym z rozwiązań jest użycietoString()
metody obiektu globalnego Object. Na przykład, jeśli masz obiekt, powiedzmy myObject, możesz użyćtoString()
metody obiektu globalnego, aby określić typ klasy myObject. Użyj tego:źródło
Powiedz, że masz
var obj;
Jeśli chcesz tylko nazwę typu obj, na przykład „Object”, „Array” lub „String”, możesz użyć tego:
źródło
Najbliżej można dostać
typeof
, ale zwraca tylko „obiekt” dla dowolnego rodzaju niestandardowego. Dla tych, patrz Jason Bunting .Edytuj, Jason z jakiegoś powodu usunął swój post, więc po prostu użyj
constructor
właściwości Object .źródło
Jeśli ktoś szukał rozwiązania współpracującego z jQuery, oto dostosowany kod wiki (oryginalny łamie jQuery).
źródło
getName
i przewraca się.Lodash ma wiele metod isMethod, więc jeśli używasz Lodash, być może taka mieszanka może być przydatna:
Dodaje metodę lodash o nazwie „identyfikuj”, która działa w następujący sposób:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
źródło
Ok, ludzie powoli budowałem metodę catch all dla tego przez kilka lat lol! Sztuką jest:
Na przykład (lub aby zobaczyć, jak poradziłem sobie z problemem) spójrz na następujący kod na github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js i wyszukaj:
classOf =
,classOfIs =
i lub lubdefineSubClass =
(bez tyknięć (`)).Jak widać, mam pewne mechanizmy, które zmuszają
classOf
mnie do nadania mi nazwy typu klas / konstruktorów, niezależnie od tego, czy jest to prymitywna, klasa zdefiniowana przez użytkownika, wartość utworzona przy użyciu natywnego konstruktora, Null, NaN itp. Dla każdej wartości javascript otrzymam unikalną nazwę typu odclassOf
funkcji. Ponadto mogę przekazać rzeczywiste konstruktory,sjl.classOfIs
aby sprawdzić typ wartości, oprócz możliwości przekazania także nazwy typu! Na przykład:`` // Proszę wybaczyć długie przestrzenie nazw! Nie miałem pojęcia o wpływie, dopóki nie użyłem ich przez chwilę (ssą haha)
``
Jeśli chcesz przeczytać więcej o tym, jak korzystam z wyżej wymienionej konfiguracji, zapoznaj się z repozytorium: https://github.com/elycruz/sjljs
Również książki z treścią na ten temat: - „Wzory JavaScript” Stoyana Stefanova. - „Javascript - przewodnik definitywny”. David Flanagan. - i wiele innych .. (szukaj w Internecie).
Możesz także szybko przetestować funkcje, o których tu mówię: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (również ścieżka 0.5.18 w adresie URL zawiera źródła z github tam minus moduły node_moduły i tak dalej).
Happy Coding!
źródło
Dość proste!
źródło
Zastosowanie
class.name
. Działa to również zfunction.name
.źródło
class
a nie instancja.