Saya membangun kembali proyek Java lama di Javascript, dan menyadari bahwa tidak ada cara yang baik untuk melakukan enum di JS.
Yang terbaik yang bisa saya dapatkan adalah:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
The const
terus Colors
dari yang ditugaskan kembali, dan pembekuan mencegah bermutasi kunci dan nilai-nilai. Saya menggunakan Simbol sehingga Colors.RED
tidak sama dengan 0
, atau apa pun selain itu sendiri.
Apakah ada masalah dengan formulasi ini? Apakah ada cara yang lebih baik?
(Saya tahu pertanyaan ini sedikit berulang, tetapi semua T / As sebelumnya cukup lama, dan ES6 memberi kita beberapa kemampuan baru.)
EDIT:
Solusi lain, yang berhubungan dengan masalah serialisasi, tapi saya percaya masih memiliki masalah ranah:
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
Dengan menggunakan referensi objek sebagai nilainya, Anda mendapatkan tabrakan-penghindaran yang sama dengan Simbol.
sumber
JSON.stringify()
. Tidak dapat membuat serial / deserializeSymbol
.Jawaban:
Saya tidak melihat apa pun.
Saya akan menciutkan dua pernyataan menjadi satu:
Jika Anda tidak menyukai boilerplate, seperti
Symbol
panggilan berulang , tentu saja Anda juga dapat menulis fungsi pembantumakeEnum
yang menciptakan hal yang sama dari daftar nama.sumber
Symbol.for
tidak tidak memiliki isu-isu lintas bidang, namun memang memiliki masalah tabrakan biasa dengan namespace benar-benar global .enum => ({[Colors.RED]: "bright red", [Colors.BLUE]: "deep blue", [Colors.GREEN]: "grass green"}[enum])
).Sementara menggunakan
Symbol
karena nilai enum berfungsi dengan baik untuk kasus penggunaan sederhana, akan berguna untuk memberikan properti ke enum. Ini dapat dilakukan dengan menggunakanObject
sebagai nilai enum yang mengandung properti.Sebagai contoh, kita dapat memberikan masing-masing
Colors
nama dan nilai hex:Termasuk properti dalam enum menghindari keharusan menulis
switch
pernyataan (dan mungkin melupakan kasus baru dengan pernyataan beralih ketika enum diperpanjang). Contoh ini juga memperlihatkan properti enum dan tipe yang didokumentasikan dengan anotasi enum JSDoc .Kesetaraan bekerja seperti yang diharapkan dengan
Colors.RED === Colors.RED
keberadaantrue
, danColors.RED === Colors.BLUE
keberadaanfalse
.sumber
Seperti disebutkan di atas, Anda juga bisa menulis
makeEnum()
fungsi pembantu:Gunakan seperti ini:
sumber
const makeEnum = (...lst) => Object.freeze(Object.assign({}, ...lst.map(k => ({[k]: Symbol(k)}))));
Kemudian gunakan sebagaiconst colors = makeEnum("Red", "Green", "Blue")
Ini adalah pendekatan pribadi saya.
sumber
Periksa bagaimana TypeScript melakukannya . Pada dasarnya mereka melakukan hal berikut:
Gunakan simbol, bekukan objek, apa pun yang Anda inginkan.
sumber
MAP[MAP[1] = 'A'] = 1;
bukanMAP[1] = 'A'; MAP['A'] = 1;
. Saya selalu mendengar bahwa menggunakan tugas sebagai ekspresi adalah gaya yang buruk. Juga, manfaat apa yang Anda dapatkan dari tugas cermin?MAP[MAP[1] = 'A'] = 1;
.x
adalah nilai Enum yang valid dengan melakukanEnum[Enum[x]] === x
. Itu tidak memecahkan masalah asli saya, tetapi bisa bermanfaat dan tidak merusak apa pun.Jika Anda tidak membutuhkan ES6 murni dan dapat menggunakan TypeScript, itu bagus
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
sumber
Anda dapat memeriksa Enumify , pustaka ES6 yang sangat bagus dan berfitur lengkap.
sumber
Mungkin solusi ini? :)
Contoh:
sumber
Saya lebih suka pendekatan @ tonethar, dengan sedikit peningkatan dan menggali untuk kepentingan memahami dengan lebih baik dasar-dasar ekosistem ES6 / Node.js. Dengan latar belakang di sisi server pagar, saya lebih suka pendekatan gaya fungsional di sekitar platform primitif, ini meminimalkan kode mengasapi, lereng licin ke lembah manajemen negara bayangan bayang-bayang karena pengenalan jenis baru dan peningkatan keterbacaan - memperjelas maksud solusi dan algoritma.
Solusi dengan TDD , ES6 , Node.js , Lodash , Jest , Babel , ESLint
sumber
Array.from(Object.assign(args))
sama sekali tidak melakukan apa pun. Anda bisa...args
langsung menggunakannya .Inilah pendekatan saya, termasuk beberapa metode pembantu
-
sumber
Anda juga dapat menggunakan paket es6-enum ( https://www.npmjs.com/package/es6-enum ). Ini sangat mudah digunakan. Lihat contoh di bawah ini:
sumber
Berikut ini adalah implementasi enumerasi Java saya dalam JavaScript.
Saya juga menyertakan unit test.
sumber
Anda bisa menggunakan Peta ES6
sumber
const x = Object.freeze({key: 'value'})
sebagai gantinya untuk mendapatkan sesuatu yang terlihat dan berperilaku seperti enum di ES6