Apa sintaks yang disukai untuk mendefinisikan enum dalam JavaScript? Sesuatu seperti:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// later on
if(currentColor == my.namespace.ColorEnum.RED) {
// whatever
}
Atau adakah idiom yang lebih disukai?
javascript
syntax
enums
David Citron
sumber
sumber
0
sebagai nomor enumerasi. Kecuali itu digunakan untuk sesuatu yang belum diatur. JS memperlakukanfalse || undefined || null || 0 || "" || '' || NaN
semua sebagai nilai yang sama bila dibandingkan dengan menggunakan==
.0 == null
mengembalikan falsefalse == 0
dan+null == 0
(dan konversi ke nomor terjadi kadang-kadang ketika Anda tidak mengharapkan itu), sementaranull == undefined
juga, dan+undefined
adalahNaN
(meskipunNaN != NaN
).Jawaban:
Karena 1.8.5 dimungkinkan untuk menyegel dan membekukan objek, jadi tentukan yang di atas sebagai:
atau
dan voila! JS enum.
Namun, ini tidak mencegah Anda menetapkan nilai yang tidak diinginkan ke variabel, yang sering kali merupakan tujuan utama enum:
Salah satu cara untuk memastikan tingkat keamanan jenis yang lebih kuat (dengan enum atau sebaliknya) adalah dengan menggunakan alat seperti TypeScript atau Flow .
Sumber
Harga tidak diperlukan tetapi saya menyimpannya untuk konsistensi.
sumber
var DaysEnum = Object.freeze ({ monday: {}, tuesday: {}, ... });
. Anda tidak perlu menentukan id, Anda bisa menggunakan objek kosong untuk membandingkan enum.if (incommingEnum === DaysEnum.monday) //incommingEnum is monday
if (Object.freeze) { Object.freeze(DaysEnum); }
({ monday: {},
dll berarti bahwa jika Anda mengkonversi objek itu ke JSON melalui stringify Anda akan mendapatkan[{"day": {}}]
yang tidak akan bekerja.var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
. Membandingkan objek seperti dalam komentar saya sebelumnya adalah JAUH LEBIH BANYAK LEMAH daripada membandingkan angka.Ini bukan jawaban yang bagus, tetapi saya akan mengatakan itu bekerja dengan baik, secara pribadi
Karena itu, karena tidak masalah apa nilainya (Anda telah menggunakan 0, 1, 2), saya akan menggunakan string yang bermakna jika Anda pernah ingin menampilkan nilai saat ini.
sumber
Object.freeze()
. Ini akan mencegah kode lain dari mengubah nilai enum. Contoh:var ColorEnum = Object.freeze({RED: 0, GREEN: 1, BLUE: 2});
instanceof
pemeriksaan. MisalnyaColorEnum.RED instanceof ColorEnum
(pengembaliantrue
). Anda juga dapat menyelesaikan instance dari namaColorEnum.fromName("RED") === ColorEnum.RED
(pengembaliantrue
). Setiap instance juga memiliki a.name()
dan.ordinal()
metode, dan enum itu sendiri memilikivalues()
metode yang mengembalikan array semua konstanta.ToString()
metode ini. Kami JS devs sudah terlalu bergantung pada hal-hal "hanya berfungsi"! Juga, seseorang harus dapat dengan cepatswitch
pada enum. Membandingkan string lebih lambat daripada membandingkan angka, jadi Anda akan mendapatkanswitch
kinerja yang sedikit lebih buruk jika Anda menggunakan string daripada bilangan bulat.MEMPERBARUI
Terima kasih untuk semua upvotes semua orang, tetapi saya tidak berpikir jawaban saya di bawah ini adalah cara terbaik untuk menulis enum di JavaScript lagi. Lihat posting blog saya untuk lebih jelasnya: Enums in JavaScript .
Mengingatkan nama sudah mungkin:
Atau, Anda bisa membuat objek nilai, sehingga Anda dapat memiliki kue dan memakannya juga:
Dalam JavaScript, karena ini adalah bahasa yang dinamis, bahkan dimungkinkan untuk menambahkan nilai enum ke set nanti:
Ingat, bidang enum (nilai, nama dan kode dalam contoh ini) tidak diperlukan untuk pemeriksaan identitas dan hanya ada untuk kenyamanan. Juga nama properti ukuran itu sendiri tidak perlu kode keras, tetapi juga dapat diatur secara dinamis. Jadi seandainya Anda hanya tahu nama untuk nilai enum baru Anda, Anda masih dapat menambahkannya tanpa masalah:
Tentu saja ini berarti bahwa beberapa asumsi tidak lagi dapat dibuat (nilai tersebut mewakili urutan yang benar untuk ukuran misalnya).
Ingat, dalam JavaScript suatu objek sama seperti peta atau tabel hash . Satu set pasangan nama-nilai. Anda dapat mengulanginya atau memanipulasi mereka tanpa tahu banyak tentang mereka sebelumnya.
Contoh
Omong-omong, jika Anda tertarik dengan namespace, Anda mungkin ingin melihat solusi saya untuk namespace sederhana dan kuat dan manajemen dependensi untuk JavaScript: Paket JS
sumber
Intinya: Anda tidak bisa.
Anda bisa memalsukannya, tetapi Anda tidak akan mendapatkan keamanan tipe. Biasanya ini dilakukan dengan membuat kamus sederhana dari nilai string yang dipetakan ke nilai integer. Sebagai contoh:
Masalah dengan pendekatan ini? Anda dapat secara tidak sengaja mendefinisikan ulang enumerant Anda, atau secara tidak sengaja memiliki nilai enumeran duplikat. Sebagai contoh:
Edit
Tentu saja,
Object.freeze
akan benar-benar memperbaiki masalah yang saya keluhkan. Saya ingin mengingatkan semua orang bahwa ketika saya menulis di atas,Object.freeze
tidak benar-benar ada.Sekarang .... sekarang membuka beberapa sangat kemungkinan yang menarik.
Edit 2
Inilah perpustakaan yang sangat bagus untuk membuat enum.
http://www.2ality.com/2011/10/enums.html
Meskipun mungkin tidak cocok dengan setiap penggunaan enum yang valid, ia berjalan sangat jauh.
sumber
var daysEnum = (function(){ var daysEnum = { monday: 1, tuesday: 2 }; return { get: function(value){ return daysEnum[value]; } } })(); daysEnum.get('monday'); // 1
Inilah yang kita semua inginkan:
Sekarang Anda dapat membuat enum:
Dengan melakukan ini, konstanta dapat diakses dengan cara biasa (YesNo.YES, Color.GREEN) dan mereka mendapatkan nilai int sekuensial (TIDAK = 0, YA = 1; MERAH = 0, HIJAU = 1, BIRU = 2).
Anda juga dapat menambahkan metode, dengan menggunakan Enum.prototype:
Sunting - peningkatan kecil - sekarang dengan varargs: (sayangnya itu tidak berfungsi dengan baik pada IE: S ... harus tetap dengan versi sebelumnya)
sumber
Di sebagian besar browser modern, ada simbol tipe data primitif yang dapat digunakan untuk membuat enumerasi. Ini akan memastikan keamanan jenis enum karena setiap nilai simbol dijamin oleh JavaScript menjadi unik, yaitu
Symbol() != Symbol()
. Sebagai contoh:Untuk menyederhanakan debugging, Anda bisa menambahkan deskripsi ke nilai enum:
Demo plunker
Pada GitHub Anda dapat menemukan pembungkus yang menyederhanakan kode yang diperlukan untuk menginisialisasi enum:
sumber
Symbol
yang dimaksudkan.Object.freeze
hanya untuk orang-orang yang belum menerima kenyataan bahwa "monkeypatch dengan risiko Anda sendiri" adalah kontrak sosial JS?toJSON
pada kelas yang mengandung untuk menggunakan pendekatan ini: stackoverflow.com/questions/58499828/…𝗣𝗹𝗮𝗶𝗻 𝗩𝗮𝗻𝗶𝗹𝗹𝗮𝗝𝗦 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲 𝗡𝗮𝗺𝗲𝘀
Mari kita langsung ke masalah: ukuran file. Setiap jawaban lain yang tercantum di sini membesar-besarkan kode Anda. Saya sampaikan kepada Anda bahwa untuk kinerja terbaik, keterbacaan kode, manajemen proyek skala besar, petunjuk sintaksis dalam banyak editor kode, dan pengurangan ukuran kode dengan minifikasi, ini adalah cara yang tepat untuk melakukan enumerasi: variabel garis bawah-notasi.
wvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwv
Seperti ditunjukkan dalam bagan di atas dan contoh di bawah, berikut adalah lima langkah mudah untuk memulai:
ENUM_
. Jika independen atau berdampingan, gunakanINDEX_
.ENUM_
atauINDEX_
, lalu nama grup, lalu garis bawah, lalu nama ramah unik untuk propertiENUMLENGTH_
,ENUMLEN_
,INDEXLENGTH_
, atauINDEXLEN_
(apakahLEN_
atauLENGTH_
preferensi pribadi) variabel disebutkan di akhir. Anda harus menggunakan variabel ini sedapat mungkin dalam kode Anda untuk memastikan bahwa menambahkan entri tambahan ke enumerasi dan menambah nilai ini tidak akan merusak kode Anda.0
tidak boleh digunakan sebagai nilai disebutkan karena0 == null
,0 == false
,0 == ""
, dan kegilaan lainnya JS. Saya serahkan kepada Anda bahwa, untuk menghindari masalah ini dan meningkatkan kinerja pada saat yang sama, selalu gunakan===
dan jangan pernah biarkan==
muncul dalam kode Anda kecuali dengantypeof
(extypeof X == "string"
). Dalam semua tahun saya menggunakan===
, saya tidak pernah memiliki masalah dengan menggunakan 0 sebagai nilai enumerasi. Jika Anda masih mudah tersinggung, maka1
dapat digunakan sebagai nilai awal dalamENUM_
enumerasi (tetapi tidak dalamINDEX_
enumerasi) tanpa penalti kinerja dalam banyak kasus.Berikut adalah bagaimana saya ingat kapan harus digunakan
INDEX_
dan kapan harus digunakanENUM_
:Namun,
ENUM_
dapat, dalam keadaan tertentu, sesuai sebagai indeks seperti ketika menghitung kejadian setiap item.Perhatikan bahwa, dalam kode di atas, sangat mudah untuk menambahkan jenis hewan peliharaan baru: Anda hanya perlu menambahkan entri baru setelah
ENUM_PET_RAT
dan memperbaruiENUMLEN_PET
sesuai. Mungkin lebih sulit dan sulit untuk menambahkan entri baru dalam sistem enumerasi lain.wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗘𝘅𝘁𝗲𝗻𝗱 𝗨𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝘀 𝗪𝗶𝘁𝗵 𝗔𝗱𝗱𝗶𝘁𝗶𝗼𝗻
Selain itu, sintaks enumerasi ini memungkinkan perluasan kelas yang jelas dan ringkas seperti yang terlihat di bawah ini. Untuk memperluas kelas, tambahkan nomor yang bertambah ke
LEN_
entri kelas induk. Kemudian, selesaikan subclass denganLEN_
entri sendiri sehingga subclass dapat diperpanjang lebih lanjut di masa depan.(Panjang: 2,450 byte)
Beberapa orang mungkin mengatakan bahwa ini kurang praktis daripada solusi lain: ia membutuhkan banyak ruang, butuh waktu lama untuk menulis, dan tidak dilapisi dengan sintaksis gula. Orang-orang itu akan benar jika mereka tidak mengubah kode mereka. Namun, tidak ada orang yang berakal yang akan meninggalkan kode yang tidak ditentukan dalam produk akhir. Untuk minifikasi ini, Closure Compiler adalah yang terbaik yang belum saya temukan. Akses online dapat ditemukan di sini . Compiler Closure dapat mengambil semua data enumerasi ini dan memasangnya, membuat Javascript Anda menjadi super duper kecil dan menjalankan super duper dengan cepat. Jadi, Minify with Closure Compiler. Mengamati.
wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗠𝗶𝗻𝗶𝗳𝘆 𝗪𝗶𝘁𝗵 𝗖𝗹𝗼𝘀𝘂𝗿𝗲 𝗖𝗼𝗺𝗽𝗶𝗹𝗲𝗿
Compiler Closure dapat melakukan beberapa optimasi yang sangat luar biasa melalui inferensi yang jauh melampaui kapasitas dari pengubah Javascript lainnya. Closure Compiler dapat inline variabel primitif diatur ke nilai tetap. Closure Compiler juga dapat membuat kesimpulan berdasarkan pada nilai yang diuraikan ini dan menghilangkan blok yang tidak digunakan dalam if-statement dan loop.
(Panjang: 605 byte)
Closure Compiler memberi Anda penghargaan untuk pengkodean yang lebih cerdas dan mengorganisasikan kode Anda dengan baik karena, sementara banyak minifiers menghukum kode terorganisir dengan ukuran file yang lebih kecil, Closure Compiler dapat menyaring semua kebersihan dan kewarasan Anda untuk menghasilkan ukuran file yang lebih kecil jika Anda menggunakan trik seperti enumerasi nama variabel. Itu, dalam satu pikiran ini, adalah grail suci pengkodean: alat yang keduanya membantu kode Anda dengan ukuran yang lebih kecil dan membantu pikiran Anda dengan melatih kebiasaan pemrograman yang lebih baik.
wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗦𝗺𝗮𝗹𝗹𝗲𝗿 𝗖𝗼𝗱𝗲 𝗦𝗶𝘇𝗲
Sekarang, mari kita lihat seberapa besar file ekuivalen tanpa enumerasi ini.
Sumber Tanpa Menggunakan Pencacahan (panjang: 1,973 byte (477 byte lebih pendek dari kode yang disebutkan!))
Diperkecil Tanpa Menggunakan Pencacahan (panjang: 843 byte ( lebih panjang 238 byte dari kode pencacahan ))
Seperti terlihat, tanpa enumerasi, kode sumber lebih pendek dengan biaya kode minified yang lebih besar. Saya tidak tahu tentang Anda; tapi saya tahu pasti bahwa saya tidak memasukkan kode sumber ke dalam produk akhir. Jadi, bentuk enumerasi ini jauh lebih unggul sehingga menghasilkan ukuran file yang lebih kecil.
wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗖𝗼𝗼𝗽𝗲𝗿𝗮𝘁𝗶𝘃𝗲 🤝 𝗕𝘂𝗴 𝗙𝗶𝘅𝗶𝗻𝗴
Keuntungan lain tentang bentuk enumerasi ini adalah dapat digunakan untuk mengelola proyek skala besar dengan mudah tanpa mengorbankan ukuran kode yang diperkecil. Ketika mengerjakan proyek besar dengan banyak orang lain, mungkin bermanfaat untuk secara eksplisit menandai dan memberi label nama variabel dengan siapa yang membuat kode sehingga pembuat kode asli dapat dengan cepat diidentifikasi untuk memperbaiki bug kolaboratif.
𝗦𝘂𝗽𝗲𝗿𝗶𝗼𝗿 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲
Selanjutnya, bentuk enumerasi ini juga jauh lebih cepat setelah minifikasi. Dalam properti bernama normal, browser harus menggunakan hashmaps untuk mencari di mana properti itu pada objek. Meskipun kompiler JIT secara cerdas men-cache lokasi ini pada objek, masih ada overhead yang luar biasa karena kasus-kasus khusus seperti menghapus properti yang lebih rendah dari objek.
Tetapi, dengan array PACKED_ELEMENTS integer non-sparse yang diindeks terus menerus , browser dapat melewati sebagian besar overhead itu karena indeks nilai dalam array internal sudah ditentukan. Ya, menurut standar ECMAScript, semua properti seharusnya diperlakukan sebagai string. Namun demikian, aspek ini dari standar ECMAScript sangat menyesatkan tentang kinerja karena semua browser memiliki optimasi khusus untuk indeks numerik dalam array.
Bandingkan kode di atas dengan kode di bawah ini.
Orang mungkin keberatan dengan kode dengan enumerasi yang nampaknya jauh lebih lama daripada kode dengan objek biasa, tetapi tampilannya bisa menipu. Penting untuk diingat bahwa ukuran kode sumber tidak sebanding dengan ukuran keluaran saat menggunakan Kompilator Penutupan epik. Mengamati.
Kode yang diperkecil tanpa enumerasi di atas dan kode yang diperkecil dengan enumerasi di bawah.
Contoh di atas menunjukkan bahwa, selain memiliki kinerja yang unggul, kode yang disebutkan juga menghasilkan ukuran file yang diperkecil lebih kecil.
wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗘𝗮𝘀𝘆 𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴
Selain itu, ceri pribadi yang satu ini di atas menggunakan bentuk enumerasi ini bersama dengan pengecualian CodeMirror editor teks dalam mode Javascript. Mode penyorotan Javascript CodeMirror menyoroti variabel lokal dalam cakupan saat ini. Dengan begitu, Anda langsung tahu kapan Anda mengetikkan nama variabel dengan benar karena jika nama variabel sebelumnya dinyatakan dengan ketika mengeksekusi kode dengan nama enumerasi yang salah ketik. Juga, alat JavaScript seperti JSLint dan Closure Compiler sangat keras untuk memberi tahu Anda ketika Anda salah ketik dalam nama variabel enumerasi. CodeMirror, browser, dan berbagai alat Javascript disatukan membuat debugging enumerasi bentuk ini sangat sederhana dan sangat mudah.
var
kata kunci, maka nama variabel tersebut akan mengubah warna khusus (cyan secara default). Bahkan jika Anda tidak menggunakan CodeMirror, maka setidaknya browser memberikan bantuan[variable name] is not defined
Dalam cuplikan di atas, Anda diberitahu dengan kesalahan karena
ENUM_COLORENUM_DNE
tidak ada.wvwwvw wvwvwvw wvwxwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvwvww
𝗖𝗼𝗻𝗰𝗹𝘂𝘀𝗶𝗼𝗻 ☑
Saya pikir aman untuk mengatakan bahwa metodologi enumerasi ini memang cara terbaik untuk pergi tidak hanya untuk ukuran kode yang diperkecil, tetapi juga untuk kinerja, debugging, dan kolaborasi.
Setelah membaca pertanyaan yang bermanfaat, saya berterima kasih kepada penulis karena telah meluangkan waktu dalam tulisan mereka dengan mengklik tanda panah kiri atas di kotak pertanyaan. Setiap kotak jawaban juga memiliki salah satu dari panah atas ini.
sumber
colors.REED
yieldsundefined
), jadi kesalahan ketik membuat teka-teki yang sulit dipahami. YEA tidak membedakan antara penggunaan enumerasi sebagai indeks dan ID, yang menyebabkan kode membingungkan di mana semuanya terlihat sama. ...Saya telah bermain-main dengan ini, karena saya suka enum saya. =)
Menggunakan
Object.defineProperty
Saya pikir saya datang dengan solusi yang agak layak.Inilah jsfiddle: http://jsfiddle.net/ZV4A6/
Dengan menggunakan metode ini .. Anda harus (secara teori) dapat memanggil dan menentukan nilai enum untuk objek apa pun, tanpa memengaruhi atribut lain dari objek itu.
Karena atribut
writable:false
ini seharusnya membuatnya aman.Jadi, Anda harus dapat membuat objek khusus, lalu memanggilnya
Enum()
. Nilai yang ditetapkan mulai dari 0 dan naik per item.sumber
return this;
pada akhir Enum yang dapat Anda lakukan:var EnumColors = {}.Enum('RED','BLUE','GREEN','YELLOW');
false
adalah standar untukwritable
,enumerable
danconfigurable
. Tidak perlu mengunyah default.Gunakan Javascript Proxies
TLDR: Tambahkan kelas ini ke metode utilitas Anda dan gunakan di seluruh kode Anda, itu mencemooh perilaku Enum dari bahasa pemrograman tradisional, dan benar-benar melempar kesalahan ketika Anda mencoba mengakses enumerator yang tidak ada atau menambah / memperbarui enumerator. Tidak perlu bergantung
Object.freeze()
.Kemudian buat enum dengan membuat instance kelas:
Penjelasan Lengkap:
Salah satu fitur yang sangat bermanfaat dari Enums yang Anda dapatkan dari bahasa tradisional adalah bahwa mereka meledak (melemparkan kesalahan waktu kompilasi) jika Anda mencoba mengakses enumerator yang tidak ada.
Selain membekukan struktur enum yang diolok-olok untuk mencegah nilai-nilai tambahan tidak sengaja / jahat ditambahkan, tidak ada jawaban lain yang membahas fitur intrinsik dari Enum.
Seperti yang mungkin Anda ketahui, mengakses anggota yang tidak ada dalam JavaScript hanya mengembalikan
undefined
dan tidak meledakkan kode Anda. Karena pencacah adalah konstanta yang ditentukan sebelumnya (yaitu hari dalam seminggu), seharusnya tidak pernah ada kasus ketika pencacah harus tidak ditentukan.Jangan salah, perilaku JavaScript untuk kembali
undefined
ketika mengakses properti yang tidak ditentukan sebenarnya adalah fitur bahasa yang sangat kuat, tetapi itu bukan fitur yang Anda inginkan ketika Anda mencoba untuk mengejek struktur Enum tradisional.Di sinilah objek Proxy bersinar. Proxy distandarisasi dalam bahasa dengan diperkenalkannya ES6 (ES2015). Berikut deskripsi dari MDN:
Mirip dengan proxy server web, proxy JavaScript dapat mencegat operasi pada objek (dengan menggunakan "jebakan", menyebutnya kait jika Anda mau) dan memungkinkan Anda untuk melakukan berbagai pemeriksaan, tindakan, dan / atau manipulasi sebelum selesai (atau dalam beberapa kasus menghentikan operasi sama sekali yang persis apa yang ingin kita lakukan jika dan ketika kita mencoba merujuk seorang enumerator yang tidak ada).
Berikut adalah contoh yang dibuat yang menggunakan objek Proxy untuk meniru Enums. Enumerator dalam contoh ini adalah Metode HTTP standar (yaitu "DAPATKAN", "POST", dll.):
ASIDE: Apa itu proxy?
Saya ingat ketika saya pertama kali melihat kata proxy di mana-mana, itu jelas tidak masuk akal bagi saya untuk waktu yang lama. Jika itu Anda saat ini, saya pikir cara mudah untuk menggeneralisasi proxy adalah dengan menganggapnya sebagai perangkat lunak, institusi, atau bahkan orang yang bertindak sebagai perantara atau perantara antara dua server, perusahaan, atau orang.
sumber
valueOf
metode default dengan menetapkannya sebagai metode instance pada kelas Enum. Namun, mengapa Anda ingin mengaksesnya dengan cara ini dibandingkan hanya mengaksesnya melalui notasi titik?logLevelEnum[settings.get("log_level")]
? menambahkanparseOrThrow
hanya akan berulang pada apa yang sudah dilakukan perangkap proxy untuk Anda.Ini adalah yang lama yang saya tahu, tetapi cara itu telah dilaksanakan melalui antarmuka TypeScript adalah:
Ini memungkinkan Anda untuk mencari
MyEnum.Bar
yang mengembalikan 1, danMyEnum[1]
yang mengembalikan "Bilah" terlepas dari urutan deklarasi.sumber
enum MyEnum { Foo, Bar, Foobar }
Di ES7 , Anda dapat melakukan ENUM yang elegan dengan mengandalkan atribut statis:
kemudian
Keuntungan (menggunakan kelas daripada objek literal) adalah memiliki kelas induk
Enum
maka semua Enums Anda akan memperluas kelas itu.sumber
new ColorEnum()
sama sekali tidak masuk akal.Enum
memiliki standar statis metode pencacah di atasnya, sepertigetValues()
,getNames()
,iterate()
, dll Jika itu yang terjadi, Anda tidak perlu reimplement mereka untuk setiap jenis baruenum
.Ini adalah solusi yang saya gunakan.
Dan Anda mendefinisikan enum Anda seperti ini:
Dan ini adalah bagaimana Anda mengakses enum Anda:
Saya biasanya menggunakan 2 metode terakhir untuk memetakan enums dari objek pesan.
Beberapa keuntungan dari pendekatan ini:
Beberapa kelemahan:
sumber
Buat objek literal:
sumber
const
tidak membuat properti objek tidak berubah, itu hanya berarti bahwa variabelModes
tidak dapat dipindahkan ke sesuatu yang lain. Untuk membuatnya lebih lengkap, gunakanObject.freeze()
bersamaconst
.Object.freeze
. Ini mencegah Closure Compiler dari inlining objek.Jika Anda menggunakan Backbone , Anda bisa mendapatkan fungsionalitas enum full-blown (temukan berdasarkan id, nama, anggota kustom) secara gratis menggunakan Backbone.Collection .
sumber
jawaban Anda terlalu rumit
sumber
Saya telah memodifikasi solusi Andre 'Fi':
Uji:
sumber
Saya datang dengan pendekatan ini yang dimodelkan setelah enum di Jawa. Ini adalah tipe-aman, sehingga Anda dapat melakukan
instanceof
pemeriksaan juga.Anda dapat mendefinisikan enum seperti ini:
Days
sekarang mengacu padaDays
enum:Pelaksanaan:
sumber
freeze
metode untuk kompatibilitas? Misalnya,if (Object.freeze) { Object.freeze(values); }
IE8 Tidak mendukung metode freeze ().
Sumber: http://kangax.github.io/compat-table/es5/ , Klik pada "Show browser usang?" di atas, dan periksa IE8 & bekukan persimpangan baris col.
Dalam proyek gim saya saat ini, saya telah menggunakan di bawah ini, karena beberapa pelanggan masih menggunakan IE8:
Kita juga bisa melakukan:
atau bahkan ini:
Yang terakhir, tampaknya paling efisien untuk string, ini mengurangi total bandwidth Anda jika Anda memiliki server & klien yang bertukar data ini.
Tentu saja, sekarang tugas Anda untuk memastikan tidak ada konflik dalam data (RE, EX, dll. Harus unik, juga 1, 2, dll. Harus unik). Perhatikan bahwa Anda perlu mempertahankan ini selamanya untuk kompatibilitas mundur.
Tugas:
Perbandingan:
sumber
Anda tidak perlu memastikan bahwa Anda tidak menetapkan angka duplikat ke nilai enum yang berbeda dengan cara ini. Objek baru akan dipakai dan ditugaskan untuk semua nilai enum.
sumber
Berikut adalah beberapa cara berbeda untuk mengimplementasikan enum TypeScript .
Cara termudah adalah dengan hanya beralih pada objek, menambahkan pasangan nilai kunci terbalik ke objek. Satu-satunya kelemahan adalah bahwa Anda harus menetapkan nilai secara manual untuk setiap anggota.
Dan ini adalah lodin mixin untuk membuat enum menggunakan string. Meskipun versi ini sedikit lebih terlibat, ia melakukan penomoran secara otomatis untuk Anda. Semua metode lodash yang digunakan dalam contoh ini memiliki standar JavaScript yang setara, sehingga Anda dapat dengan mudah mengubahnya jika Anda mau.
sumber
Saya baru saja menerbitkan paket NPM gen_enum memungkinkan Anda membuat struktur data Enum dalam Javascript dengan cepat:
Satu hal yang menyenangkan tentang alat kecil ini adalah di lingkungan modern (termasuk browser nodejs dan IE 9+) objek Enum yang dikembalikan tidak dapat diubah.
Untuk informasi lebih lanjut silakan checkout https://github.com/greenlaw110/enumjs
Pembaruan
Saya
gen_enum
paket usang dan menggabungkan fungsi ke dalam paket constjs , yang menyediakan lebih banyak fitur termasuk objek yang tidak dapat diubah, deserialisasi string JSON, konstanta string dan pembuatan bitmap dll. Checkout https://www.npmjs.com/package/constjs untuk informasi lebih lanjutUntuk meng-upgrade dari
gen_enum
keconstjs
hanya mengubah pernyataanuntuk
sumber
Solusi paling sederhana:
Membuat
Dapatkan Nilai
Dapatkan Kunci
sumber
Saya telah membuat kelas Enum yang dapat mengambil nilai DAN nama di O (1). Itu juga dapat menghasilkan Array Objek yang berisi semua Nama dan Nilai.
Anda dapat menggunakannya seperti ini:
Untuk mengambil nilai (seperti Enums di C #):
Untuk mengambil nama untuk suatu nilai (dapat bersifat mendua ketika menempatkan nilai yang sama untuk nama yang berbeda):
Untuk mendapatkan array dengan setiap nama & nilai dalam suatu objek:
Akan menghasilkan:
Anda juga bisa mendapatkan opsi pemilihan html dengan mudah:
Yang berlaku:
sumber
Meskipun hanya metode statis (dan bukan properti statis) yang didukung dalam ES2015 (lihat di sini juga, §15.2.2.2), anehnya Anda dapat menggunakan di bawah ini dengan Babel dengan
es2015
preset:Saya menemukan ini berfungsi seperti yang diharapkan bahkan di seluruh modul (misalnya mengimpor
CellState
enum dari modul lain) dan juga ketika saya mengimpor modul menggunakan Webpack.Keuntungan metode ini memiliki lebih dari sebagian besar jawaban lain adalah bahwa Anda dapat menggunakannya bersama pemeriksa tipe statis (misalnya Flow ) dan Anda dapat menegaskan, pada saat pengembangan menggunakan pengecekan tipe statis, bahwa variabel, parameter, dll. Anda adalah spesifik
CellState
" enum "daripada enum lain (yang tidak mungkin dibedakan jika Anda menggunakan objek atau simbol umum).memperbarui
Kode di atas memiliki kekurangan karena memungkinkan seseorang untuk membuat objek tipe tambahan
CellState
(walaupun seseorang tidak dapat menetapkannya ke bidang statisCellState
sejak dibekukan). Namun, kode lebih halus di bawah ini menawarkan keuntungan sebagai berikut:CellState
dapat dibuatyang
values
fungsi yang kembali semua contoh enum tidak harus menciptakan nilai kembali di atas, pengguna (dan rawan kesalahan) cara.sumber
es7 way, (iterator, freeze), penggunaan:
kode:
sumber
Ini adalah bagaimana typescript menerjemahkannya
enum
ke dalam Javascript:Sekarang:
Pada awalnya saya bingung mengapa
obj[1]
kembali'Active'
, tetapi kemudian menyadari bahwa mati sederhana - operator Tugas memberikan nilai dan kemudian mengembalikannya:sumber
Anda dapat melakukan sesuatu seperti ini
Seperti yang didefinisikan di perpustakaan ini. https://github.com/webmodule/foo/blob/master/foo.js#L217
Contoh lengkap https://gist.github.com/lnt/bb13a2fd63cdb8bce85fd62965a20026
sumber
Cara cepat dan sederhana adalah:
sumber
Pada saat penulisan, Oktober 2014 - jadi di sini adalah solusi kontemporer. Saya menulis solusi sebagai Modul Node, dan telah menyertakan tes menggunakan Mocha dan Chai, serta garis bawahJS. Anda dapat dengan mudah mengabaikannya, dan ambil saja kode Enum jika diinginkan.
Melihat banyak posting dengan pustaka yang terlalu berbelit-belit, dll. Solusi untuk mendapatkan dukungan enum dalam Javascript sangat sederhana sehingga sebenarnya tidak diperlukan. Ini kodenya:
File: enums.js
Dan tes untuk menggambarkan apa yang memberi Anda:
file: enumsSpec.js
Seperti yang Anda lihat, Anda mendapatkan pabrik Enum, Anda bisa mendapatkan semua kunci hanya dengan memanggil enum.keys, dan Anda bisa mencocokkan kunci itu sendiri dengan konstanta integer. Dan Anda dapat menggunakan kembali pabrik dengan nilai yang berbeda, dan mengekspor Enum yang dihasilkan menggunakan pendekatan modular Node.
Sekali lagi, jika Anda hanya pengguna biasa, atau di peramban dll, ambil saja bagian kode pabrik, berpotensi menghapus pustaka garis bawah juga jika Anda tidak ingin menggunakannya dalam kode Anda.
sumber
Mudah digunakan, saya pikir. https://stackoverflow.com/a/32245370/4365315
MEMPERBARUI:
Ada kode pembantu saya (
TypeHelper
).Tampilkan cuplikan kode
sumber