Apakah ada JavaScript setara dengan Java 's class.getName()
?
javascript
Ewen Cartwright
sumber
sumber
Jawaban:
Tidak ada .
ES2015 Update : nama
class Foo {}
adalahFoo.name
. Namathing
kelas, apa punthing
jenisnya, adalahthing.constructor.name
. Konstruktor builtin di lingkungan ES2015 memilikiname
properti yang benar ; misalnya(2).constructor.name
adalah"Number"
.Tapi di sini ada berbagai peretasan yang semuanya jatuh dengan satu atau lain cara:
Berikut adalah retasan yang akan melakukan apa yang Anda butuhkan - perlu diketahui bahwa ia memodifikasi prototipe Object, sesuatu yang disukai orang (biasanya karena alasan yang baik)
Sekarang, semua objek Anda akan memiliki fungsi
getName()
,, yang akan mengembalikan nama konstruktor sebagai string. Saya telah menguji iniFF3
danIE7
saya tidak dapat berbicara untuk implementasi lainnya.Jika Anda tidak ingin melakukan itu, berikut adalah diskusi tentang berbagai cara menentukan jenis dalam JavaScript ...
Saya baru-baru ini memperbarui ini menjadi sedikit lebih lengkap, meskipun tidak terlalu sulit. Koreksi menyambut ...
Menggunakan
constructor
properti ...Setiap
object
memiliki nilai untukconstructor
propertinya, tetapi tergantung pada bagaimanaobject
itu dibangun serta apa yang ingin Anda lakukan dengan nilai itu, itu mungkin atau mungkin tidak berguna.Secara umum, Anda dapat menggunakan
constructor
properti untuk menguji jenis objek seperti:Jadi, itu bekerja dengan cukup baik untuk sebagian besar kebutuhan. Yang mengatakan ...
Peringatan
Tidak akan berfungsi sama sekali dalam banyak kasus
Pola ini, meskipun rusak, cukup umum:
Objects
dibangun melaluinew Thingy
akan memilikiconstructor
properti yang menunjuk keObject
, bukanThingy
. Jadi kita jatuh tepat pada awalnya; Anda tidak bisa mempercayaiconstructor
basis kode yang tidak Anda kontrol.Warisan Berganda
Contoh yang tidak terlalu jelas adalah menggunakan multiple inheritance:
Hal-hal sekarang tidak berfungsi seperti yang Anda perkirakan:
Jadi, Anda mungkin mendapatkan hasil yang tidak terduga jika
object
pengujian Anda memilikiobject
set yang berbedaprototype
. Ada beberapa cara di luar ruang lingkup diskusi ini.Ada kegunaan lain untuk
constructor
properti, beberapa di antaranya menarik, yang lain tidak begitu banyak; untuk saat ini kami tidak akan membahas penggunaan tersebut karena tidak relevan dengan diskusi ini.Tidak akan bekerja lintas-bingkai dan lintas-jendela
Menggunakan
.constructor
untuk pengecekan tipe akan pecah ketika Anda ingin memeriksa jenis objek yang berasal dariwindow
objek yang berbeda , katakan bahwa iframe atau jendela sembulan. Ini karena ada versi berbeda dari setiap tipe inticonstructor
di setiap `jendela ', yaituMenggunakan
instanceof
operator ...The
instanceof
operator adalah cara yang bersih dari pengujianobject
jenis juga, tapi memiliki potensi masalah sendiri, seperticonstructor
properti.Tetapi
instanceof
gagal bekerja untuk nilai-nilai literal (karena literal tidakObjects
)Literal perlu dibungkus
Object
agarinstanceof
dapat bekerja, misalnyaThe
.constructor
cek berfungsi dengan baik untuk literal karena.
pemanggilan metode implisit membungkus literal di jenis objek masing-masingMengapa dua titik untuk 3? Karena Javascript menginterpretasikan titik pertama sebagai titik desimal;)
Tidak akan bekerja lintas-bingkai dan lintas-jendela
instanceof
juga tidak akan bekerja di jendela yang berbeda, untuk alasan yang sama seperticonstructor
pemeriksaan properti.Menggunakan
name
properticonstructor
properti ...Tidak berfungsi sama sekali dalam banyak kasus
Sekali lagi, lihat di atas; itu sangat umum untuk
constructor
menjadi benar-benar salah dan tidak berguna.TIDAK bekerja di <IE9
Menggunakan
myObjectInstance.constructor.name
akan memberi Anda string yang berisi namaconstructor
fungsi yang digunakan, tetapi tunduk pada peringatan tentangconstructor
properti yang disebutkan sebelumnya.Untuk IE9 dan yang lebih baru, Anda dapat mendukung-monyet :
Versi terbaru dari artikel tersebut. Ini ditambahkan 3 bulan setelah artikel itu diterbitkan, ini adalah versi yang direkomendasikan untuk digunakan oleh penulis artikel Matthew Scharley. Perubahan ini terinspirasi oleh komentar yang menunjukkan potensi jebakan dalam kode sebelumnya.
Menggunakan Object.prototype.toString
Ternyata, karena rincian pos ini , Anda dapat menggunakan
Object.prototype.toString
- level rendah dan implementasi generiktoString
- untuk mendapatkan tipe untuk semua tipe bawaanOrang bisa menulis fungsi pembantu pendek seperti
untuk menghapus cruft dan dapatkan di hanya ketik nama
Namun, itu akan kembali
Object
untuk semua jenis yang ditentukan pengguna.Peringatan untuk semua ...
Semua ini tunduk pada satu masalah potensial, dan itu adalah pertanyaan tentang bagaimana objek tersebut dibangun. Berikut adalah berbagai cara membangun objek dan nilai-nilai yang akan dikembalikan oleh metode pengecekan tipe yang berbeda:
Meskipun tidak semua permutasi hadir dalam serangkaian contoh ini, mudah-mudahan ada cukup untuk memberi Anda gagasan tentang bagaimana hal-hal yang berantakan mungkin tergantung pada kebutuhan Anda. Jangan berasumsi apa-apa, jika Anda tidak mengerti apa yang Anda cari, Anda mungkin berakhir dengan melanggar kode di mana Anda tidak mengharapkannya karena kurangnya mengasyikkan kehalusan.
CATATAN:
Diskusi
typeof
operator mungkin tampak sebagai kelalaian mencolok, tetapi itu benar-benar tidak berguna dalam membantu mengidentifikasi apakah suatuobject
jenis diberikan, karena sangat sederhana. Memahami di manatypeof
berguna itu penting, tetapi saya saat ini tidak merasa bahwa itu sangat relevan dengan diskusi ini. Pikiranku terbuka untuk berubah. :)sumber
constructor
metode objek (baik dengan.toString()
atau.name
) akan gagal berfungsi jika Javascript Anda telah diperkecil dengan alat seperti uglify, atau pipa aset Rails. Minifikasi mengganti nama konstruktor, sehingga Anda akan berakhir dengan nama kelas yang salah sepertin
. Jika Anda berada dalam skenario ini, Anda mungkin ingin secara manual mendefinisikanclassName
properti pada objek Anda dan menggunakannya.Jawaban Jason Bunting memberi saya cukup petunjuk untuk menemukan apa yang saya butuhkan:
Jadi, misalnya, dalam potongan kode berikut:
myInstance.constructor.name
akan kembali"MyObject"
.sumber
function getType(o) { return o && o.constructor && o.constructor.name }
Trik kecil yang saya gunakan:
sumber
class Square
, namanya adalahSquare.name
/MySquare.constructor.name
bukanSquare.prototype.name
; dengan memakainame
fungsi konstruktor, ia tidak mencemari prototipe atau contoh apa pun, tetapi dapat diakses dari keduanya.Memperbarui
Lebih tepatnya, saya pikir OP meminta fungsi yang mengambil nama konstruktor untuk objek tertentu. Dalam hal Javascript,
object
tidak memiliki tipe tetapi merupakan tipe dan dengan sendirinya . Namun, objek yang berbeda dapat memiliki konstruktor yang berbeda .Catatan: contoh di bawah ini sudah usang.
Sebuah posting blog dihubungkan oleh Christian Sciberras berisi contoh yang baik tentang bagaimana untuk melakukannya. Yaitu, dengan memperluas prototipe Obyek:
sumber
test.getClassName()
vsgetClassName.apply(test)
.Menggunakan Object.prototype.toString
Ternyata, karena rincian pos ini, Anda dapat menggunakan Object.prototype.toString - implementasi toString tingkat rendah dan generik - untuk mendapatkan tipe untuk semua tipe bawaan
Orang bisa menulis fungsi pembantu pendek seperti
sumber
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Berikut ini adalah solusi yang saya temukan yang memecahkan kekurangan instanceof. Itu dapat memeriksa tipe objek dari cross-windows dan cross-frame dan tidak memiliki masalah dengan tipe primitif.
isInstance memerlukan dua parameter: objek dan tipe. Trik sebenarnya untuk cara kerjanya adalah memeriksa apakah objek berasal dari jendela yang sama dan jika tidak mendapatkan jendela objek.
Contoh:
Argumen tipe juga bisa menjadi fungsi callback yang mengembalikan konstruktor. Fungsi panggilan balik akan menerima satu parameter yang merupakan jendela dari objek yang disediakan.
Contoh:
Satu hal yang perlu diingat adalah bahwa IE <9 tidak menyediakan konstruktor pada semua objek sehingga tes di atas untuk NodeList akan mengembalikan false dan juga isInstance (waspada, "Function") akan mengembalikan false.
sumber
Saya sebenarnya mencari hal yang sama dan menemukan pertanyaan ini. Inilah cara saya mendapatkan tipe: jsfiddle
sumber
Anda harus menggunakan
somevar.constructor.name
seperti:sumber
Gunakan
constructor.name
saat Anda bisa, dan regex berfungsi saat saya tidak bisa.sumber
Fungsi kind () dari Agave.JS akan kembali:
Ini bekerja pada semua objek dan primitif JS, terlepas dari bagaimana mereka dibuat , dan tidak memiliki kejutan. Contoh:
Angka
NaN
String
Boolean
Array
Benda
tanggal
Fungsi
tidak terdefinisi
batal
sumber
Anda bisa menggunakan
instanceof
operator untuk melihat apakah suatu objek adalah turunan dari yang lain, tetapi karena tidak ada kelas, Anda tidak bisa mendapatkan nama kelas.sumber
instanceof
hanya memeriksa apakah suatu objek mewarisi dari objek lain. Misalnya,[]
pewarisan sederhana dari Array, tetapi Array juga mewarisi dari Obyek. Karena sebagian besar objek memiliki beberapa tingkat warisan, menemukan prototipe terdekat adalah teknik yang lebih baik. Lihat jawaban saya untuk caranya.Berikut ini adalah implementasi berdasarkan jawaban yang diterima :
Kami hanya menggunakan properti konstruktor ketika kami tidak punya pilihan lain.
sumber
Anda dapat menggunakan operator "instanceof" untuk menentukan apakah suatu objek adalah turunan dari kelas tertentu atau tidak. Jika Anda tidak tahu nama tipe objek, Anda bisa menggunakan properti konstruktornya. Properti konstruktor objek, adalah referensi ke fungsi yang digunakan untuk menginisialisasi mereka. Contoh:
Sekarang c1.constructor adalah referensi ke
Circle()
fungsi. Anda juga dapat menggunakantypeof
operator, tetapitypeof
operator menunjukkan informasi yang terbatas. Salah satu solusinya adalah dengan menggunakantoString()
metode Object global object. Misalnya jika Anda memiliki objek, katakan myObject, Anda dapat menggunakantoString()
metode Obyek global untuk menentukan jenis kelas myObject. Gunakan ini:sumber
Katakan sudah
var obj;
Jika Anda hanya ingin nama jenis objek, seperti "Objek", "Array", atau "String", Anda dapat menggunakan ini:
sumber
Yang paling dekat Anda dapatkan adalah
typeof
, tetapi hanya mengembalikan "objek" untuk semua jenis jenis kustom. Untuk itu, lihat Jason Bunting .Sunting, Jason menghapus posnya karena alasan tertentu, jadi gunakan saja
constructor
properti Object .sumber
Jika ada yang mencari solusi yang bekerja dengan jQuery, di sini adalah kode wiki yang disesuaikan (istirahat asli jQuery).
sumber
getName
dan jatuh.Lodash memiliki banyak isMethods jadi jika Anda menggunakan Lodash mungkin mixin seperti ini dapat berguna:
Itu menambahkan metode untuk lodash yang disebut "mengidentifikasi" yang berfungsi sebagai berikut:
Plunker: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
sumber
Ok, orang-orang saya telah perlahan-lahan membangun semua metode untuk ini selama beberapa tahun lol! Caranya adalah dengan:
Sebagai contoh (atau untuk melihat bagaimana saya mengatasi masalah) lihat kode berikut di github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js dan cari:
classOf =
,,classOfIs =
dan ataudefineSubClass =
(tanpa backticks (`)).Seperti yang Anda lihat, saya memiliki beberapa mekanisme untuk memaksa
classOf
agar selalu memberi saya kelas / konstruktor jenis nama terlepas dari apakah itu primitif, kelas yang ditentukan pengguna, nilai yang dibuat menggunakan konstruktor asli, Null, NaN, dll. Untuk setiap nilai javascript tunggal saya akan mendapatkan nama tipe unik dariclassOf
fungsi. Selain itu saya dapat meneruskan konstruktor yang sebenarnya kesjl.classOfIs
untuk memeriksa tipe nilai selain untuk dapat lulus dalam nama tipe itu juga! Jadi misalnya:`` `// Maafkan ruang nama yang panjang! Saya tidak tahu dampaknya sampai setelah menggunakannya sebentar (mereka payah haha)
`` `
Jika Anda tertarik untuk membaca lebih lanjut tentang bagaimana saya menggunakan pengaturan yang disebutkan di atas, lihat repo: https://github.com/elycruz/sjljs
Juga buku-buku dengan konten pada subjek: - "Pola JavaScript" oleh Stoyan Stefanov. - "Javascript - Panduan Definitif." oleh David Flanagan. - dan banyak lainnya .. (search le` web).
Anda juga dapat dengan cepat menguji fitur yang saya bicarakan di sini: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (juga jalur 0,5.18 di url memiliki sumber dari github di sana minus node_modules dan semacamnya).
Selamat Coding!
sumber
Cukup sederhana!
sumber
Gunakan
class.name
. Ini juga berfungsi denganfunction.name
.sumber
class
dan bukan contoh.