Stworzyłem obiekt JavaScript, ale jak mogę określić klasę tego obiektu?
Chcę czegoś podobnego do .getClass()
metody Java .
javascript
oop
DNB5brims
źródło
źródło
class
typu. To nie maclass
słów kluczowych iclass
składni do tworzenia prototypów, w której metody mogą łatwiej dostępsuper
.Odpowiedzi:
W
getClass()
JavaScript nie ma dokładnego odpowiednika Javy . Wynika to głównie z tego, że JavaScript jest językiem opartym na prototypach , w przeciwieństwie do języka Java opartego na klasach .W zależności od tego, czego potrzebujesz
getClass()
, w JavaScript jest kilka opcji:typeof
instanceof
obj.
constructor
func.
prototype
,proto
.isPrototypeOf
Kilka przykładów:
Uwaga: jeśli kompilujesz swój kod za pomocą Uglify, zmieni on nieglobalne nazwy klas. Aby temu zapobiec, Uglify ma
--mangle
parametr, który można ustawić na wartość false, używając łyka lub chrząknięcia .źródło
func.prototype
tak powinno być (tak, funkcje są obiektami, aleprototype
właściwość dotyczy tylko obiektów funkcyjnych).instanceof
/isPrototypeOf()
i niestandardowy__proto__
Object.getPrototypeOf()
constructor.name
jeśli twój kod jest minimalizowany. Nazwa funkcji zmieni się dowolnie.construction.name
jako token, który należy zignorować / nie zminimalizować. Poza tym większość (jeśli nie wszystkie) oprogramowanie minimalizatora zapewnia reguły wyjątków.to niezawodna metoda w nowoczesnych przeglądarkach.
Function.name
został oficjalnie dodany do standardu w ES6, dzięki czemu jest to zgodny ze standardami sposób uzyskiwania „klasy” obiektu JavaScript jako ciągu. Jeśli obiekt zostanie utworzony za pomocą instancjivar obj = new MyClass()
, zwróci „MyClass”.Zwróci „Number” dla liczb, „Array” dla tablic i „Function” dla funkcji itp. Ogólnie działa zgodnie z oczekiwaniami. Jedynymi przypadkami, w których nie udaje się, jest utworzenie obiektu bez prototypu za pośrednictwem
Object.create( null )
lub utworzenie instancji obiektu z funkcji anonimowo zdefiniowanej (nienazwanej).Pamiętaj również, że jeśli minimalizujesz swój kod, porównywanie z ciągami znaków zakodowanych na stałe nie jest bezpieczne. Na przykład zamiast sprawdzać, czy
obj.constructor.name == "MyType"
zamiast tego sprawdźobj.constructor.name == MyType.name
. Lub po prostu porównaj same konstruktory, jednak to nie zadziała ponad granicami DOM, ponieważ istnieją różne instancje funkcji konstruktora w każdym DOM, dlatego porównanie obiektów na ich konstruktorach nie zadziała.źródło
Function.name
nie jest (jeszcze) częścią standardu JavaScript. Jest obecnie obsługiwany w Chrome i Firefox, ale nie w IE (10).obj.constructor.name
działa tylko dla nazwanych funkcji. To znaczy, jeśli zdefiniujęvar Foo = function() {}
, to dlavar foo = new Foo()
,foo.constructor.name
da ci pusty ciąg.constructor.name
jeśli twój kod jest minimalizowany. Nazwa funkcji zmieni się dowolnie.constructor.name
zachowuje się zgodnie z oczekiwaniami dzięki obsłudze nowej klasy w ES6.Ta funkcja zwraca
"Undefined"
wartości niezdefiniowane i wartości"Null"
zerowe.Dla wszystkich innych wartości
CLASSNAME
wyodrębnia się -part[object CLASSNAME]
, co jest wynikiem użyciaObject.prototype.toString.call(value)
.źródło
"Object"
.return obj.constructor.name
. To daje te same wyniki, a także obsługuje obiekty nienatywne.Aby uzyskać „pseudo klasę”, można uzyskać funkcję konstruktora, poprzez
zakładając, że
constructor
jest ustawione poprawnie podczas dziedziczenia - co jest przez coś takiego:i te dwie linie, wraz z:
wskaże
woofie.constructor
naDog
. Zauważ, żeDog
jest to funkcja konstruktora iFunction
obiekt. Ale możesz zrobićif (woofie.constructor === Dog) { ... }
.Jeśli chcesz uzyskać nazwę klasy jako ciąg, znalazłem następujące działające dobrze:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
Przechodzi do funkcji konstruktora, konwertuje ją na ciąg znaków i wyodrębnia nazwę funkcji konstruktora.
Pamiętaj, że
obj.constructor.name
mógł działać dobrze, ale nie jest to standard. To jest na Chrome i Firefox, ale nie na IE, w tym IE 9 lub IE 10 RTM.źródło
Możesz uzyskać odwołanie do funkcji konstruktora, która utworzyła obiekt, używając właściwości konstruktora :
Jeśli chcesz potwierdzić typ obiektu w czasie wykonywania, możesz użyć operatora instanceof :
źródło
Zgodnie z nieprzerwanym zapisem kompatybilności wstecznej, ECMAScript 6, JavaScript nadal nie ma
class
typu (choć nie wszyscy to rozumieją). To nie maclass
słowa kluczowego w ramach swojejclass
składni do tworzenia prototypów, ale nadal nie coś, co nazywa klasa . JavaScript nie jest teraz i nigdy nie był klasycznym językiem OOP . Mówienie o JS w kategoriach klasy jest albo mylące, albo jest oznaką jeszcze nieokreślonego dziedziczenia prototypowego (po prostu utrzymywanie go w stanie rzeczywistym).Oznacza to, że
this.constructor
wciąż jest doskonałym sposobem na uzyskanie odniesienia doconstructor
funkcji. Ithis.constructor.prototype
jest to sposób na uzyskanie dostępu do samego prototypu. Ponieważ nie jest to Java, nie jest to klasa. Jest to obiekt prototypowy, z którego tworzona jest instancja. Oto przykład użycia cukru syntaktycznego ES6 do stworzenia łańcucha prototypów:Oto, co wyprowadza za pomocą
babel-node
:Masz to! W 2016 r. W
class
JavaScript jest słowo kluczowe, ale nadal nie ma typu klasy.this.constructor
to najlepszy sposób na uzyskanie funkcji konstruktora,this.constructor.prototype
najlepszy sposób na uzyskanie dostępu do samego prototypu.źródło
Miałem teraz okazję do ogólnej pracy i skorzystałem z tego:
to jedyny sposób, w jaki udało mi się uzyskać nazwę klasy według typu input, jeśli nie masz instancji obiektu.
(napisane w ES2017)
notacja kropkowa również działa dobrze
źródło
W przypadku klas Javascript w ES6 możesz użyć
object.constructor
. W przykładowej klasie poniżejgetClass()
metoda zwraca klasę ES6 zgodnie z oczekiwaniami:Jeśli tworzysz instancję klasy z
getClass
metody, upewnij się, że otaczasz ją nawiasami npruffles = new ( fluffy.getClass() )( args... );
źródło
Znajduję
object.constructor.toString()
zwrot[object objectClass]
w IE, a niefunction objectClass () {}
w chome. Myślę więc, że kod w http://blog.magnetiq.com/post/514962277/finding-out-out-class-names-of-javascript-objects może nie działać dobrze w IE.I poprawiłem kod w następujący sposób:kod:
źródło
W javascript nie ma klas, ale myślę, że chcesz nazwę konstruktora i
obj.constructor.toString()
powie ci, czego potrzebujesz.źródło
.name
..name
nie jest zdefiniowany nawet w IE 9Zgadzam się z dfa, dlatego uważam prototye za klasę, gdy nie znaleziono nazwanej klasy
Oto ulepszona funkcja opublikowana przez Eli Graya, pasująca do mojego sposobu myślenia
źródło
Jeśli chcesz nie tylko uzyskać klasę, ale także WYDŁUŻYĆ ją tylko o instancję, napisz:
chodźmy
więc aby rozszerzyć A, mając instancję, użyj tylko:
źródło
Sugeruję użycie
Object.prototype.constructor.name
:źródło
Oto implementacja
getClass()
igetInstance()
Możesz uzyskać odwołanie do klasy Object za pomocą
this.constructor
.Z kontekstu instancji:
Ze statycznego kontekstu:
źródło
this.constructor
?Możesz także zrobić coś takiego
Dzięki temu dowiesz się, czy dane wejściowe są klasy, czy nie
źródło
JavaScript jest językiem bezklasowym: nie ma klas, które definiowałyby zachowanie klasy statycznie jak w Javie. JavaScript używa prototypów zamiast klas do definiowania właściwości obiektów, w tym metod i dziedziczenia. Możliwe jest symulowanie wielu funkcji opartych na klasach za pomocą prototypów w JavaScript.
źródło
class
typu. To nie maclass
słów kluczowych iclass
składni do tworzenia prototypów, w której metody mogą łatwiej dostępsuper
.Pytanie wydaje się już udzielone, ale OP chce uzyskać dostęp do klasy i obiektu, tak jak robimy to w Javie, a wybrana odpowiedź nie jest wystarczająca (imho).
Dzięki poniższemu wyjaśnieniu możemy uzyskać klasę obiektu (tak naprawdę w javascript nazywa się to prototypem).
Możesz dodać taką właściwość:
Ale
.last
właściwość będzie dostępna tylko dlaarr
obiektu, który jest utworzony z prototypu Array. Aby więc.last
właściwość była dostępna dla wszystkich obiektów utworzonych z prototypu Array, musimy zdefiniować.last
właściwość dla prototypu Array:Problem polega na tym, że musisz wiedzieć, do jakiego typu obiektu (prototypu) należą zmienne „
arr
” i „arr2
”! Innymi słowy, jeśli nie znasz typu klasy (prototypu) obiektu „arr
”, nie będziesz w stanie zdefiniować dla nich właściwości. W powyższym przykładzie wiemy, że arr jest instancją obiektu Array, dlatego użyliśmy Array.prototype do zdefiniowania właściwości dla Array. Ale co, jeśli nie znamy klasy (prototypu) „arr
”?Jak widać, nie wiedząc, że „
arr
” jest tablicą, możemy dodać nową właściwość, po prostu odwołując się do klasy „arr
” za pomocą „arr.__proto__
”.Udało nam się uzyskać dostęp do prototypu „
arr
”, nie wiedząc, że jest to instancja Array i myślę, że o to poprosił OP.źródło
__proto__
Nieruchomość jest przestarzała i nie ma prawie żadnej przewagi nadprototype
obiektem.