Apakah ada cara 'harmonis' untuk mendapatkan nama kelas dari instance kelas ES6? Selain daripada
someClassInstance.constructor.name
Saat ini saya mengandalkan implementasi Traceur. Dan sepertinya Babel memiliki polyfill untuk Function.name
sementara Traceur tidak.
Singkatnya: tidak ada cara lain di ES6 / ES2015 / Harmony, dan tidak ada ATM yang diharapkan di ES.Berikutnya.
Ini mungkin menyediakan pola yang berguna untuk aplikasi sisi server yang tidak dijinakkan tetapi tidak diinginkan dalam aplikasi yang dimaksudkan untuk browser / desktop / seluler.
Babel menggunakancore-js
untuk polyfill Function.name
, itu harus dimuat secara manual untuk aplikasi Traceur dan TypeScript yang sesuai.
javascript
ecmascript-6
traceur
Estus Flask
sumber
sumber
instance.constructor.name
danclass.name
kembalikan nama kelas dalam ES6 yang tepat.someClassInstance.constructor.name
akan hancur jika Anda mengubah kode Anda..constructor
.Jawaban:
someClassInstance.constructor.name
persis cara yang tepat untuk melakukan ini. Transpiler mungkin tidak mendukung ini, tetapi itu adalah cara standar per spesifikasi. (name
Properti fungsi yang dideklarasikan melalui produksi ClassDeclaration diatur dalam 14.5.15 , langkah 6.)sumber
someClassInstance.constructor
adalah Fungsi. Semua Fungsi memilikiname
properti yang disetel sesuai namanya. Itu sebabnya babel tidak perlu melakukan apa pun. Silakan lihat developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Seperti kata @Domenic, gunakan
someClassInstance.constructor.name
. @Esteban menyebutkan dalam komentar ituJadi, untuk mengakses nama kelas secara statis, lakukan hal berikut (ini bekerja dengan BTW versi Babel saya. Menurut komentar pada @Domenic, jarak tempuh Anda mungkin berbeda).
Memperbarui
Babel baik-baik saja, tetapi uglify / minification akhirnya menyebabkan saya bermasalah. Saya membuat game, dan saya sedang membuat hash sumber Sprite dikumpulkan (di mana kuncinya adalah nama fungsi). Setelah minifikasi, setiap fungsi / kelas diberi nama
t
. Ini membunuh hash. Saya menggunakanGulp
dalam proyek ini, dan setelah membaca dokumen gulp-uglify saya menemukan ada parameter untuk mencegah ini variabel / fungsi nama mangling terjadi. Jadi, dalam gulpfile saya, saya berubah.pipe($.uglify())
untuk.pipe($.uglify({ mangle: false }))
Ada trade-off kinerja vs keterbacaan di sini. Tidak mengacaukan nama-nama akan menghasilkan (sedikit) membangun file yang lebih besar (lebih banyak sumber daya jaringan) dan berpotensi eksekusi kode lebih lambat (kutipan diperlukan - mungkin BS). Di sisi lain, jika saya menyimpannya sama saya harus mendefinisikan secara manual
getClassName
pada setiap kelas ES6 - pada tingkat statis dan contoh. Tidak, terima kasih!Memperbarui
Setelah diskusi dalam komentar, sepertinya menghindari
.name
konvensi yang mendukung mendefinisikan fungsi-fungsi tersebut adalah paradigma yang baik. Hanya membutuhkan beberapa baris kode, dan akan memungkinkan minifikasi penuh dan generalisasi kode Anda (jika digunakan di perpustakaan). Jadi saya kira saya berubah pikiran dan secara manual akan menentukangetClassName
kelas saya. Terima kasih @estus! . Getter / Setters biasanya merupakan ide yang bagus dibandingkan dengan akses variabel langsung, terutama dalam aplikasi berbasis klien.sumber
reserved
opsi Uglify (daftar kelas dapat diperoleh dengan regexp atau apa pun).name
pola yang rapi mungkin hanya win-win Hal yang sama dapat diterapkan pada Node, tetapi pada tingkat yang lebih rendah (misalnya aplikasi Electron dikaburkan). Sebagai aturan praktis, saya akan bergantung padaname
kode server, tetapi tidak dalam kode browser dan tidak di perpustakaan umum.name
kode DRYer untuk mengekstrak nama entitas yang menggunakan kelas (layanan, plugin, dll) dari nama kelas, tetapi pada akhirnya saya menemukan bahwa itu menduplikasinya secara eksplisit dengan prop statis (id
,_name
) hanyalah pendekatan yang paling solid. Alternatif yang baik adalah tidak peduli dengan nama kelas, gunakan kelas itu sendiri (objek fungsi) sebagai pengidentifikasi untuk entitas yang dipetakan ke kelas ini dan diimport
mana pun diperlukan (pendekatan yang digunakan oleh Angular 2 DI).Mendapatkan nama kelas langsung dari kelas
Jawaban sebelumnya menjelaskan bahwa itu
someClassInstance.constructor.name
berfungsi dengan baik, tetapi jika Anda secara terprogram mengubah nama kelas menjadi string dan tidak ingin membuat turunan hanya untuk itu, ingat bahwa:Dan, karena setiap fungsi memiliki
name
properti, cara lain yang bagus untuk mendapatkan string dengan nama kelas Anda adalah dengan hanya melakukan:Berikut ini adalah contoh bagus mengapa ini berguna.
Memuat komponen web
Seperti yang diajarkan oleh dokumentasi MDN kepada kami, ini adalah cara Anda memuat komponen web:
Di mana
YourComponent
kelas membentang dariHTMLElement
. Karena dianggap praktik yang baik untuk memberi nama kelas komponen Anda setelah tag komponen itu sendiri, alangkah baiknya menulis fungsi pembantu yang dapat digunakan semua komponen Anda untuk mendaftar sendiri. Jadi, inilah fungsi itu:Jadi yang perlu Anda lakukan adalah:
Yang bagus karena lebih sedikit kesalahan daripada menulis tag komponen sendiri. Untuk menyelesaikannya, ini adalah
upperCamelCaseToSnakeCase()
fungsinya:sumber
Untuk transpilasi babel (sebelum minifikasi)
Jika Anda menggunakan Babel dengan
@babel/preset-env
, dimungkinkan untuk menjaga definisi kelas tanpa mengubahnya menjadi fungsi (yang menghapusconstructor
properti)Anda dapat menjatuhkan beberapa kompatibilitas browser lama dengan konfigurasi ini di
babel.config / babelrc
:Untuk minifikasi babel (setelah transpilasi)
Sepertinya tidak ada solusi mudah saat ini ... Kita perlu melihat pengecualian yang membingungkan.
sumber
class Foo {}
akan diperkecil menjadi sesuatu seperticlass a{}
dengan target apa pun. Tidak akan adaFoo
kata dalam kode sumber yang diperkecil.export class Foo{}
tidak dapat secara efisien dijelaskan lebih lanjut tetapi ini mungkin berbeda di tempat lain, kita tidak dapat mengetahui bagaimana tepatnya tanpa memiliki ide yang baik apa yang terjadi dengan potongan kode tertentu pada waktu pembuatan. Bagaimanapun, ini tidak berubah sejak 2015. Itu selalu mungkin untuk beberapa konfigurasi kompilasi dan kode. Dan saya katakan kemungkinan ini masih terlalu rapuh untuk menggunakan nama kelas untuk logika aplikasi. Nama kelas yang Anda andalkan dapat menjadi sampah setelah satu perubahan kode sumber yang tidakconstructor.name
masih berfungsi dalam versi yang