Jaka jest preferowana składnia do definiowania wyliczeń w JavaScript? Coś jak:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// later on
if(currentColor == my.namespace.ColorEnum.RED) {
// whatever
}
Czy jest bardziej preferowany idiom?
javascript
syntax
enums
David Citron
źródło
źródło
0
jako numeru wyliczenia. Chyba że jest używany do czegoś, co nie zostało ustawione. JS traktujefalse || undefined || null || 0 || "" || '' || NaN
wszystko jako tę samą wartość w porównaniu z użyciem==
.0 == null
zwraca falsefalse == 0
i+null == 0
(a konwersje na liczby zdarzają się czasem, gdy się tego nie spodziewasz), podczas gdynull == undefined
też i+undefined
jestNaN
(chociażNaN != NaN
).Odpowiedzi:
Od 1.8.5 istnieje możliwość uszczelnienia i zamrożenia obiektu, więc zdefiniuj powyższe jako:
lub
i voila! JS wylicza.
Nie uniemożliwia to jednak przypisania niepożądanej wartości zmiennej, która często jest głównym celem wyliczeń:
Jednym ze sposobów zapewnienia większego stopnia bezpieczeństwa typu (z wyliczeniami lub w inny sposób) jest użycie narzędzia takiego jak TypeScript lub Flow .
Źródło
Cytaty nie są potrzebne, ale zachowałem je dla zachowania spójności.
źródło
var DaysEnum = Object.freeze ({ monday: {}, tuesday: {}, ... });
. Nie musisz podawać identyfikatora, możesz po prostu użyć pustego obiektu do porównania wyliczeń.if (incommingEnum === DaysEnum.monday) //incommingEnum is monday
if (Object.freeze) { Object.freeze(DaysEnum); }
({ monday: {},
zauważyć , że robienie itp. Oznacza, że jeśli przekształcisz ten obiekt w JSON za pomocą stringify, otrzymasz to,[{"day": {}}]
co nie zadziała.var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
. Porównywanie obiektów jak w moim poprzednim komentarzu jest DUŻO WOLNIEJSZE niż porównywanie liczb.To nie jest duża odpowiedź, ale powiedziałbym, że osobiście działa dobrze
Powiedziawszy to, ponieważ nie ma znaczenia, jakie są wartości (użyłeś 0, 1, 2), użyłbym znaczącego ciągu na wypadek, gdybyś chciał kiedyś wyświetlić bieżącą wartość.
źródło
Object.freeze()
. Zapobiegnie to zmianie przez inny kod wartości wyliczenia. Przykład:var ColorEnum = Object.freeze({RED: 0, GREEN: 1, BLUE: 2});
instanceof
kontrole. Na przykładColorEnum.RED instanceof ColorEnum
(zwracatrue
). Możesz także rozwiązać instancję z nazwyColorEnum.fromName("RED") === ColorEnum.RED
(zwracatrue
). Każdy przypadek jest również.name()
i w.ordinal()
sposób, a sam wyliczenia mavalues()
metodę returnd tablicę wszystkich stałych.ToString()
metoda. My, twórcy JS, jesteśmy już zbyt zależni od rzeczy „po prostu działających”! Ponadto, powinno być możliwe szybkieswitch
wyliczenie. Porównywanie ciągów jest wolniejsze niż porównywanie liczb, więc osiągniesz nieco gorsząswitch
wydajność, jeśli użyjesz ciągów zamiast liczb całkowitych.AKTUALIZACJA
Dziękuję za wszystkie głosy poparcia dla wszystkich, ale nie sądzę, że moja odpowiedź poniżej jest najlepszym sposobem na pisanie wyliczeń w JavaScript. Zobacz mój post na blogu, aby uzyskać więcej informacji: Wyliczenia w JavaScript .
Alarmowanie nazwy jest już możliwe:
Alternatywnie możesz utworzyć wartości obiektów, abyś mógł zjeść ciasto i zjeść je:
W JavaScript, ponieważ jest to język dynamiczny, możliwe jest nawet dodanie wartości enum do zestawu później:
Pamiętaj, że pola wyliczenia (wartość, nazwa i kod w tym przykładzie) nie są potrzebne do sprawdzania tożsamości i są tam tylko dla wygody. Również nazwa właściwości size nie musi być zakodowana na stałe, ale może być również ustawiana dynamicznie. Załóżmy więc, że znasz tylko nazwę swojej nowej wartości wyliczeniowej, nadal możesz ją dodać bez problemów:
Oczywiście oznacza to, że nie można już przyjąć pewnych założeń (ta wartość reprezentuje na przykład prawidłową kolejność dla rozmiaru).
Pamiętaj, że w JavaScript obiekt jest jak mapa lub tablica skrótów . Zestaw par nazwa-wartość. Możesz je przeglądać lub w inny sposób nimi manipulować, nie wiedząc o nich wiele wcześniej.
Przykład
A tak przy okazji, jeśli interesujesz się przestrzeniami nazw, możesz rzucić okiem na moje rozwiązanie dla prostego, ale potężnego zarządzania przestrzenią nazw i zależnościami dla JavaScript: Pakiety JS
źródło
Konkluzja: Nie możesz.
Możesz to sfałszować, ale nie uzyskasz bezpieczeństwa typu. Zazwyczaj odbywa się to poprzez utworzenie prostego słownika wartości ciągów odwzorowanych na wartości całkowite. Na przykład:
Problem z tym podejściem? Możesz przypadkowo przedefiniować numerator lub przypadkowo mieć zduplikowane wartości modułu. Na przykład:
Edytować
Absolutnie
Object.freeze
całkowicie rozwiązałoby problem, na który narzekałem. Chciałbym przypomnieć wszystkim, że kiedy napisałem powyższe,Object.freeze
tak naprawdę nie istniały.Teraz .... teraz otwiera kilka bardzo interesujących możliwości.
Edycja 2
Oto bardzo dobra biblioteka do tworzenia wyliczeń.
http://www.2ality.com/2011/10/enums.html
Chociaż prawdopodobnie nie pasuje do każdego prawidłowego użycia wyliczeń, idzie bardzo daleko.
źródło
var daysEnum = (function(){ var daysEnum = { monday: 1, tuesday: 2 }; return { get: function(value){ return daysEnum[value]; } } })(); daysEnum.get('monday'); // 1
Oto, czego wszyscy chcemy:
Teraz możesz tworzyć swoje wyliczenia:
W ten sposób można uzyskać dostęp do stałych w zwykły sposób (Tak Nie Nie TAK, Kolor ZIELONY) i otrzymują one sekwencyjną wartość int (NIE = 0, TAK = 1; CZERWONY = 0, ZIELONY = 1, NIEBIESKI = 2).
Możesz także dodać metody, używając Enum.prototype:
Edycja - mała poprawka - teraz z varargs: (niestety nie działa poprawnie na IE: S ... powinna pozostać przy poprzedniej wersji)
źródło
W większości nowoczesnych przeglądarek, jest symbolem prymitywny typ danych, które mogą być wykorzystywane do tworzenia wyliczenie. Zapewni to bezpieczeństwo typu wyliczenia, ponieważ każda wartość symbolu jest gwarantowana przez JavaScript jako unikalny, tj
Symbol() != Symbol()
. Na przykład:Aby uprościć debugowanie, możesz dodać opis do wartości wyliczeniowych:
Demo gry Plunker
Na GitHub możesz znaleźć opakowanie, które upraszcza kod wymagany do zainicjowania wyliczenia:
źródło
Symbol
jest przeznaczona.Object.freeze
tylko dla osób, które nie zaakceptowały faktu, że „małpka na własne ryzyko” jest umową społeczną JS?toJSON
określeniu klasy zawierającej, aby zastosować to podejście: stackoverflow.com/questions/58499828/...𝗣𝗹𝗮𝗶𝗻 𝗩𝗮𝗻𝗶𝗹𝗹𝗮𝗝𝗦 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲 𝗡𝗮𝗺𝗲𝘀
Przejdźmy od razu do problemu: rozmiaru pliku. Każda inna odpowiedź wymieniona tutaj powoduje, że Twój kod jest skrajnie rozdęty. Przedstawiam wam, że dla najlepszej możliwej wydajności, czytelności kodu, zarządzania projektami na dużą skalę, podpowiedzi składniowych w wielu edytorach kodu i zmniejszenia rozmiaru kodu przez zmniejszenie, jest to właściwy sposób wykonywania wyliczeń: zmienne podkreślenia.
wvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvw
Jak pokazano w powyższej tabeli i poniższym przykładzie, oto pięć łatwych kroków do rozpoczęcia:
ENUM_
. Jeśli jest to niezależne lub używane obok siebie, użyjINDEX_
.ENUM_
lubINDEX_
, następnie nazwa grupy, następnie podkreślenie, a następnie unikalna przyjazna nazwa właściwościENUMLENGTH_
,ENUMLEN_
,INDEXLENGTH_
, lubINDEXLEN_
(niezależnie od tegoLEN_
czyLENGTH_
jest preferencje osobiste) Zmienna wyliczone na samym końcu. Powinieneś używać tej zmiennej tam, gdzie to możliwe w swoim kodzie, aby mieć pewność, że dodanie dodatkowego wpisu do wyliczenia i zwiększenie tej wartości nie spowoduje uszkodzenia kodu.0
nie powinny być stosowane jako Numeracja dlatego0 == null
,0 == false
,0 == ""
i inne szaleństwa JS. Przekazuję Ci, że aby uniknąć tego problemu i jednocześnie zwiększyć wydajność, zawsze używaj===
i nigdy nie pozwól, aby==
pojawiał się w kodzie, z wyjątkiemtypeof
(extypeof X == "string"
). Przez wszystkie lata użytkowania===
nigdy nie miałem problemu z użyciem 0 jako wartości wyliczenia. Jeśli nadal jesteś wrażliwy,1
może być używany jako wartość początkowa wENUM_
wyliczeniach (ale nie wINDEX_
wyliczeniach) bez utraty wydajności w wielu przypadkach.Oto, jak pamiętam, kiedy
INDEX_
i kiedy użyćENUM_
:Jednakże,
ENUM_
może w pewnych okolicznościach być odpowiednie jako wskaźnik taki jak przy liczeniu liczby wystąpień każdego elementu.Zauważ, że w powyższym kodzie naprawdę łatwo jest dodać nowy rodzaj zwierzaka: wystarczy dodać nowy wpis
ENUM_PET_RAT
iENUMLEN_PET
odpowiednio go zaktualizować . Dodanie nowego wpisu w innych systemach wyliczania może być trudniejsze i bardziej problematyczne.wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗘𝘅𝘁𝗲𝗻𝗱 𝗨𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝘀 𝗪𝗶𝘁𝗵 𝗔𝗱𝗱𝗶𝘁𝗶𝗼𝗻
Ponadto ta składnia wyliczeń pozwala na jasne i zwięzłe rozszerzanie klas, jak pokazano poniżej. Aby przedłużyć klasę, dodaj rosnący numer do
LEN_
pozycji klasy nadrzędnej. Następnie zakończ podklasę własnymLEN_
wpisem, aby podklasa mogła zostać w przyszłości rozszerzona.(Długość: 2450 bajtów)
Niektórzy mogą powiedzieć, że jest to mniej praktyczne niż inne rozwiązania: zwalnia mnóstwo miejsca, zajmuje dużo czasu do pisania i nie jest pokryte składnią cukrową. Ci ludzie mieliby rację, gdyby nie zminimalizowali swojego kodu. Jednak żadna rozsądna osoba nie zostawiłaby nieuprawnionego kodu w produkcie końcowym. Do tej minimalizacji Kompilator Zamknięcia jest najlepszym, jaki jeszcze nie znalazłem. Dostęp online można znaleźć tutaj . Kompilator zamykania jest w stanie pobrać wszystkie dane wyliczenia i wstawić je, dzięki czemu JavaScript jest bardzo mały i szybko działa. Dlatego Minify z kompilatorem zamknięcia. Przestrzegać.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗠𝗶𝗻𝗶𝗳𝘆 𝗪𝗶𝘁𝗵 𝗖𝗹𝗼𝘀𝘂𝗿𝗲 𝗖𝗼𝗺𝗽𝗶𝗹𝗲𝗿
Kompilator Closure jest w stanie przeprowadzić pewne niewiarygodne optymalizacje za pomocą wnioskowania, które wykraczają daleko poza możliwości jakiegokolwiek innego minifigatora JavaScript. Kompilator zamknięcia może wstawiać pierwotne zmienne ustawione na stałą wartość. Kompilator zamknięcia może także dokonywać wnioskowania na podstawie tych wartości wprowadzonych i eliminować nieużywane bloki w instrukcjach if i pętlach.
(Długość: 605 bajtów)
Closure Compiler nagradza cię za inteligentniejsze kodowanie i porządne porządkowanie kodu, ponieważ podczas gdy wielu minifikatorów karze zorganizowany kod większym zmniejszonym rozmiarem pliku, Closure Compiler jest w stanie przesiać całą twoją czystość i rozsądek, aby uzyskać jeszcze mniejszy rozmiar pliku, jeśli używasz sztuczek jak wyliczenia nazw zmiennych. To, w tym jednym umyśle, jest święty graal kodowania: narzędzie, które zarówno wspomaga twój kod przy mniejszym pomniejszonym rozmiarze, jak i pomaga twojemu umysłowi, trenując lepsze nawyki programistyczne.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗦𝗺𝗮𝗹𝗹𝗲𝗿 𝗖𝗼𝗱𝗲 𝗦𝗶𝘇𝗲
Zobaczmy teraz, jak duży byłby równoważny plik bez tych wyliczeń.
Źródło bez
użycia wyliczeń (długość: 1973 bajtów (477 bajtów krótszych niż wyliczony kod!)) Zminimalizowane bez użycia wyliczeń (długość: 843 bajtów (238 bajtów dłuższych niż wyliczony kod ))
Jak widać, bez wyliczeń kod źródłowy jest krótszy kosztem większego zminimalizowanego kodu. Nie wiem jak ty; ale wiem na pewno, że nie dołączam kodu źródłowego do produktu końcowego. Dlatego ta forma wyliczania jest znacznie lepsza, ponieważ powoduje mniejsze mniejsze pliki.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗖𝗼𝗼𝗽𝗲𝗿𝗮𝘁𝗶𝘃𝗲 🤝 𝗕𝘂𝗴 𝗙𝗶𝘅𝗶𝗻𝗴
Kolejną zaletą tej formy wyliczania jest to, że można jej użyć do łatwego zarządzania projektami na dużą skalę bez poświęcania zminimalizowanego rozmiaru kodu. Podczas pracy nad dużym projektem z wieloma innymi osobami, może być korzystne wyraźne oznaczenie i oznaczenie nazw zmiennych, kto utworzył kod, aby można było szybko zidentyfikować oryginalnego twórcę kodu w celu wspólnego usuwania błędów.
𝗦𝘂𝗽𝗲𝗿𝗶𝗼𝗿 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲
Ponadto ta forma wyliczenia jest również znacznie szybsza po zminimalizowaniu. W normalnych nazwanych właściwościach przeglądarka musi używać skrótów, aby sprawdzić, gdzie właściwość znajduje się na obiekcie. Chociaż kompilatory JIT inteligentnie buforują tę lokalizację na obiekcie, nadal występują ogromne koszty ogólne ze względu na specjalne przypadki, takie jak usunięcie niższej właściwości z obiektu.
Ale dzięki ciągłym, nierzadkim macierzom PACKED_ELEMENTS z indeksowaniem liczb całkowitych , przeglądarka może pominąć znaczną część tego narzutu, ponieważ indeks wartości w tablicy wewnętrznej jest już określony. Tak, zgodnie ze standardem ECMAScript wszystkie właściwości powinny być traktowane jako ciągi znaków. Niemniej jednak ten aspekt standardu ECMAScript jest bardzo mylący pod względem wydajności, ponieważ wszystkie przeglądarki mają specjalne optymalizacje dla indeksów numerycznych w tablicach.
Porównaj powyższy kod z kodem poniżej.
Można sprzeciwić się kodowi z wyliczeniami, które wydają się znacznie dłuższe niż kod ze zwykłymi obiektami, ale wygląd może być mylący. Ważne jest, aby pamiętać, że rozmiar kodu źródłowego nie jest proporcjonalny do rozmiaru wyjściowego podczas korzystania z epickiego kompilatora Closure. Przestrzegać.
Zminimalizowany kod bez wyliczeń znajduje się powyżej, a zminimalizowany kod z wyliczeniami znajduje się poniżej.
Powyższy przykład pokazuje, że oprócz doskonałej wydajności, wyliczony kod skutkuje również mniejszym zminimalizowanym rozmiarem pliku.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗘𝗮𝘀𝘆 𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴
Co więcej, osobista wiśnia tego na górze korzysta z tej formy wyliczania wraz z edytorem tekstu CodeMirror w trybie Javascript. Tryb podświetlania składni JavaScript CodeMirror wyróżnia zmienne lokalne w bieżącym zakresie. W ten sposób od razu wiesz, kiedy poprawnie wpiszesz nazwę zmiennej, ponieważ jeśli nazwa zmiennej została wcześniej zadeklarowana
var
słowem kluczowym, wówczas nazwa zmiennej zmienia kolor na specjalny (domyślnie błękitny). Nawet jeśli nie korzystasz z CodeMirror, przynajmniej przeglądarka rzuca pomocne[variable name] is not defined
wyjątek podczas wykonywania kodu z błędnie wpisanymi nazwami wyliczeń. Ponadto narzędzia JavaScript, takie jak JSLint i kompilator zamknięcia, bardzo głośno mówią o błędach w nazwie zmiennej wyliczeniowej. CodeMirror, przeglądarka i różne narzędzia JavaScript razem sprawiają, że debugowanie tej formy wyliczenia jest bardzo proste i bardzo łatwe.W powyższym fragmencie został wyświetlony komunikat o błędzie, ponieważ
ENUM_COLORENUM_DNE
nie istnieje.wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvwvwvwvwvwwwww
𝗖𝗼𝗻𝗰𝗹𝘂𝘀𝗶𝗼𝗻 ☑
Myślę, że można bezpiecznie powiedzieć, że ta metodologia wyliczania jest rzeczywiście najlepszym sposobem, aby przejść nie tylko do zminimalizowania rozmiaru kodu, ale także do wydajności, debugowania i współpracy.
Po przeczytaniu pomocnego pytania dziękuję autorowi za poświęcenie czasu na pisanie, klikając lewą górną strzałkę w górę w polu pytania. Każde pole odpowiedzi ma także jedną z tych strzałek w górę.
źródło
colors.REED
zbiorówundefined
), więc literówki tworzą nieuchwytne zagadki. YEA nie rozróżnia użycia wyliczeń jako indeksów i identyfikatorów, co prowadzi do mylącego kodu, w którym wszystko wygląda tak samo. …Bawiłem się tym, ponieważ uwielbiam moje wyliczenia. =)
Za pomocą
Object.defineProperty
myślę, że wymyśliłem nieco realne rozwiązanie.Oto jsfiddle: http://jsfiddle.net/ZV4A6/
Korzystając z tej metody ... powinieneś (teoretycznie) móc wywoływać i definiować wartości wyliczeniowe dla dowolnego obiektu, bez wpływu na inne atrybuty tego obiektu.
Ze względu na atrybut powinien
writable:false
to zrobić zrobić to wpisać bezpieczne.Powinieneś być w stanie stworzyć niestandardowy obiekt, a następnie wywołać
Enum()
go. Przypisane wartości zaczynają się od 0 i przyrost na sztukę.źródło
return this;
na końcu Enum, możesz zrobić:var EnumColors = {}.Enum('RED','BLUE','GREEN','YELLOW');
false
jest domyślnąwritable
,enumerable
aconfigurable
. Nie ma potrzeby żucia nad domyślnymi.Użyj Javascript Proxy
TLDR: Dodaj tę klasę do metod narzędziowych i używaj jej w całym kodzie, wyśmiewa zachowanie Enum z tradycyjnych języków programowania i faktycznie generuje błędy, gdy próbujesz uzyskać dostęp do nieistniejącego modułu wyliczającego lub dodać / zaktualizować moduł wyliczający. Nie musisz polegać
Object.freeze()
.Następnie utwórz wyliczenia, tworząc instancję klasy:
Pełne objaśnienie:
Jedną z bardzo korzystnych cech Enums, które otrzymujesz z tradycyjnych języków, jest to, że wysadzają w powietrze (generują błąd czasu kompilacji), jeśli spróbujesz uzyskać dostęp do modułu wyliczającego, który nie istnieje.
Oprócz zamrożenia wyśmiewanej struktury wyliczeniowej, aby zapobiec przypadkowemu / złośliwemu dodaniu dodatkowych wartości, żadna z pozostałych odpowiedzi nie dotyczy tej nieodłącznej cechy Enums.
Jak zapewne wiesz, dostęp do nieistniejących członków w JavaScript po prostu powraca
undefined
i nie wysadza twojego kodu. Ponieważ moduły wyliczające są predefiniowanymi stałymi (tj. Dniami tygodnia), nigdy nie powinno być przypadku, gdy moduł wyliczający powinien być niezdefiniowany.Nie zrozumcie mnie źle, zachowanie JavaScript powrotu
undefined
podczas uzyskiwania dostępu do nieokreślonych właściwości jest w rzeczywistości bardzo potężną funkcją języka, ale nie jest to funkcja, której chcesz, gdy próbujesz kpić z tradycyjnych struktur Enum.To tutaj świecą obiekty proxy. Serwer proxy ustandaryzowano w języku wraz z wprowadzeniem ES6 (ES2015). Oto opis z MDN:
Podobnie jak proxy serwera WWW, proxy JavaScript mogą przechwytywać operacje na obiektach (za pomocą „pułapek”, w razie potrzeby nazywać je hakami) i umożliwiać wykonywanie różnych kontroli, akcji i / lub manipulacji przed ich zakończeniem (lub w niektórych przypadkach całkowite zatrzymanie operacji, co dokładnie chcemy zrobić, jeśli i kiedy spróbujemy odwołać się do modułu wyliczającego, który nie istnieje).
Oto wymyślony przykład, który używa obiektu Proxy do naśladowania Enums. Moduł wyliczający w tym przykładzie to standardowe metody HTTP (tj. „GET”, „POST” itp.):
NA BOK: Co to do cholery jest proxy?
Pamiętam, kiedy po raz pierwszy zobaczyłem słowo proxy wszędzie, zdecydowanie nie miało to dla mnie sensu przez długi czas. Jeśli tak, to uważam, że łatwym sposobem na uogólnienie serwerów proxy jest myślenie o nich jak o oprogramowaniu, instytucjach, a nawet ludziach, którzy działają jako pośrednicy lub pośrednicy między dwoma serwerami, firmami lub ludźmi.
źródło
valueOf
metodę, określając ją jako metodę instancji w klasie Enum. Dlaczego jednak chcesz uzyskać do niego dostęp w ten sposób, a nie tylko poprzez notację kropkową?logLevelEnum[settings.get("log_level")]
? dodawanieparseOrThrow
byłoby po prostu powtarzalne do tego, co pułapki proxy już dla ciebie robią.Jest to stary, który znam, ale sposób, w jaki został zaimplementowany za pośrednictwem interfejsu TypeScript, to:
Umożliwia to sprawdzenie,
MyEnum.Bar
które zwracają 1, aMyEnum[1]
które zwracają „Pasek” niezależnie od kolejności deklaracji.źródło
enum MyEnum { Foo, Bar, Foobar }
W ES7 możesz wykonać elegancki ENUM w oparciu o atrybuty statyczne:
następnie
Zaletą (używania klasy zamiast dosłownego obiektu) jest posiadanie klasy nadrzędnej,
Enum
wtedy wszystkie twoje Enumy rozszerzą tę klasę.źródło
new ColorEnum()
nie ma absolutnie żadnego sensu.Enum
posiada standardowe statyczne metody wyliczający na to, jakgetValues()
,getNames()
,iterate()
, itd. Jeśli o to chodzi, nie masz do reimplement je dla każdego nowego rodzajuenum
.To jest rozwiązanie, którego używam.
I definiujesz swoje wyliczenia w ten sposób:
I w ten sposób uzyskujesz dostęp do swoich wyliczeń:
Zwykle używam ostatnich 2 metod do mapowania wyliczeń z obiektów wiadomości.
Niektóre zalety tego podejścia:
Niektóre wady:
źródło
Utwórz literał obiektu:
źródło
const
nie sprawia, że właściwości obiektu są niezmienne, oznacza tylko, że zmiennejModes
nie można przypisać do czegoś innego. Aby uczynić go bardziej kompletnym, użyjObject.freeze()
obokconst
.Object.freeze
. Zapobiega to wstawianiu obiektu przez kompilator zamknięcia.Jeśli używasz Backbone , możesz uzyskać pełną funkcjonalność wyliczania (znaleźć według identyfikatora, nazwy, niestandardowych członków) za darmo, korzystając z Backbone.Collection .
źródło
twoje odpowiedzi są zbyt skomplikowane
źródło
Zmodyfikowałem rozwiązanie Andre „Fi”:
Test:
źródło
Wymyśliłem to podejście, które jest wzorowane na wyliczeniach w Javie. Są one bezpieczne dla typu, więc możesz wykonać
instanceof
kontrole.Możesz zdefiniować wyliczenia w następujący sposób:
Days
teraz odnosi się doDays
wyliczenia:Implementacja:
źródło
freeze
metoda zgodności wstecznej? Np.if (Object.freeze) { Object.freeze(values); }
IE8 nie obsługuje metody freeze ().
Źródło: http://kangax.github.io/compat-table/es5/ , Kliknij „Pokaż przestarzałe przeglądarki?” u góry i sprawdź IE8 i zamroź przecięcie wiersza col.
W moim obecnym projekcie gry wykorzystałem poniżej, ponieważ niewielu klientów nadal korzysta z IE8:
Możemy również zrobić:
a nawet to:
Ten ostatni, wydaje się najbardziej wydajny dla łańcucha, zmniejsza całkowitą przepustowość, jeśli serwer i klient wymieniają te dane.
Oczywiście teraz Twoim obowiązkiem jest upewnienie się, że nie ma konfliktów w danych (RE, EX itp. Muszą być unikalne, również 1, 2 itp. Powinny być unikalne). Pamiętaj, że musisz zachować je na zawsze, aby zachować zgodność wsteczną.
Zadanie:
Porównanie:
źródło
Nie musisz się upewnić, że w ten sposób nie przypisujesz duplikatów różnym wartościom wyliczenia. Nowy obiekt jest tworzony w postaci instancji i przypisywany do wszystkich wartości wyliczania.
źródło
Oto kilka różnych sposobów implementacji wyliczeń TypeScript .
Najłatwiej jest po prostu iterować obiekt, dodając do niego odwrócone pary klucz-wartość. Jedyną wadą jest to, że musisz ręcznie ustawić wartość dla każdego elementu.
A oto mixina lodash, aby utworzyć wyliczenie za pomocą łańcucha. Ta wersja jest nieco bardziej zaangażowana, ale automatycznie wykonuje numerację. Wszystkie metody lodash zastosowane w tym przykładzie mają zwykły odpowiednik JavaScript, więc możesz je łatwo zmienić, jeśli chcesz.
źródło
Właśnie opublikowałem pakiet NPM gen_enum umożliwia szybkie tworzenie struktury danych Enum w JavaScript:
Jedną fajną rzeczą w tym małym narzędziu jest to, że w nowoczesnym środowisku (w tym w przeglądarkach nodejs i IE 9+) zwracany obiekt Enum jest niezmienny.
Aby uzyskać więcej informacji, sprawdź https://github.com/greenlaw110/enumjs
Aktualizacje
Ja przestarzała
gen_enum
pakiet i scalam funkcję w pakiet constjs , który zapewnia więcej funkcji, w tym niezmienne obiekty, deserializację ciągów JSON, stałe ciągów i generowanie bitmap itp. Kasa https://www.npmjs.com/package/constjs Więcej informacji naAby uaktualnić
gen_enum
doconstjs
wystarczy zmienić oświadczeniedo
źródło
Najprostsze rozwiązanie:
Stwórz
Uzyskaj wartość
Weź klucz
źródło
Stworzyłem klasę Enum, która może pobierać wartości ORAZ nazwy w O (1). Może także generować tablicę obiektów zawierającą wszystkie nazwy i wartości.
Możesz to zainicjować w następujący sposób:
Aby pobrać wartość (jak Enums w C #):
Aby pobrać nazwę dla wartości (może być niejednoznaczny przy wprowadzaniu tej samej wartości dla różnych nazw):
Aby uzyskać tablicę z każdą nazwą i wartością w obiekcie:
Wygeneruje:
Możesz również łatwo uzyskać opcje wyboru HTML:
Który zawiera:
źródło
Mimo że w ES2015 obsługiwane są tylko metody statyczne (a nie właściwości statyczne) (patrz także tutaj , §15.2.2.2), co ciekawe, możesz użyć poniższej wersji z Babel ze wstępnym
es2015
ustawieniem:CellState
Przekonałem się, że działa to zgodnie z oczekiwaniami, nawet między modułami (np. Importując wyliczenie z innego modułu), a także podczas importowania modułu za pomocą Webpacka.Zaletą tej metody w porównaniu z większością innych odpowiedzi jest to, że można jej używać wraz ze sprawdzaniem typu statycznego (np. Flow ), a także w trakcie opracowywania przy użyciu sprawdzania typu statycznego można stwierdzić, że zmienne, parametry itp. Są określone
CellState
„ enum ”zamiast jakiegoś innego wyliczenia (którego nie można byłoby odróżnić, jeśli użyjesz ogólnych obiektów lub symboli).aktualizacja
Powyższy kod ma wadę polegającą na tym, że pozwala tworzyć dodatkowe obiekty typu
CellState
(nawet jeśli nie można ich przypisać do pól statycznych,CellState
ponieważ jest zamrożony). Mimo to poniższy, bardziej dopracowany kod oferuje następujące zalety:CellState
można już tworzyćvalues
funkcja, która zwraca wszystkie instancje wyliczenia nie musi tworzyć wartość zwracaną w powyższym, ręcznym (i podatne na błędy) sposób.źródło
sposób es7, (iterator, zamrażanie), użycie:
kod:
źródło
Oto w jaki sposób maszynopis tłumaczy to
enum
na JavaScript:Teraz:
Na początku byłem zdezorientowany, dlaczego
obj[1]
zwraca'Active'
, ale potem zdałem sobie sprawę, że jest to bardzo proste - operator przypisania przypisuje wartość, a następnie zwraca:źródło
Możesz zrobić coś takiego
Jak zdefiniowano w tej bibliotece. https://github.com/webmodule/foo/blob/master/foo.js#L217
Kompletny przykład https://gist.github.com/lnt/bb13a2fd63cdb8bce85fd62965a20026
źródło
Szybki i prosty sposób to:
źródło
Stan na piśmie, październik 2014 r - oto współczesne rozwiązanie. Piszę rozwiązanie jako moduł węzła, i zawarłem test z użyciem Mocha i Chai, a także podkreślenie JS. Możesz łatwo je zignorować i po prostu wziąć kod Enum, jeśli wolisz.
Widziałem wiele postów z nadmiernie skomplikowanymi bibliotekami itp. Rozwiązanie w celu uzyskania obsługi enum w Javascript jest tak proste, że tak naprawdę nie jest potrzebne. Oto kod:
Plik: enums.js
I test ilustrujący to, co daje:
plik: enumsSpec.js
Jak widać, masz fabrykę Enum, możesz zdobyć wszystkie klucze, po prostu wywołując enum.keys, i możesz dopasować same klucze do stałych całkowitych. Możesz ponownie wykorzystać fabrykę z różnymi wartościami i wyeksportować wygenerowane wyliczenia za pomocą modułowego podejścia Node.
Jeszcze raz, jeśli jesteś zwykłym użytkownikiem lub w przeglądarce itp., Po prostu weź fabryczną część kodu, potencjalnie usuwając bibliotekę podkreślenia, jeśli nie chcesz używać go w kodzie.
źródło
Myślę, że jest łatwy w użyciu. https://stackoverflow.com/a/32245370/4365315
AKTUALIZACJA:
Tam są moje kody pomocnicze (
TypeHelper
).Pokaż fragment kodu
źródło