Bagaimana Anda menggunakan bebek mengetik dalam javascript tanpa selalu memeriksa properti dan metode?

11

Saya tahu javascript menggunakan mengetik bebek dan pada awalnya saya pikir ini akan membuat polimorfisme mudah dibandingkan dengan bahasa yang sangat diketik seperti C #. Tapi sekarang fungsi saya yang mengambil argumen dipenuhi dengan hal-hal seperti:

if(myObj.hasSomeProperty())

atau

if(myObj.hasSomeMethod())

atau

if(isNumber(myParam))

dll.

Ini benar-benar jelek bagiku. Saya berasal dari latar belakang C # dan saya menemukan antarmuka yang didefinisikan jauh lebih baik.

Saya bertanya-tanya apakah saya salah mencoba menerapkan strategi yang efektif dalam bahasa yang diketik secara statis dan ada beberapa cara yang lebih baik untuk melakukan ini dalam javascript?

Saya tahu saya tidak bisa memeriksa, tetapi melacak kesalahan waktu javascript dapat menjadi mimpi buruk karena tidak selalu terjadi di mana kesalahan sebenarnya terjadi dalam kode.

Pasukan
sumber
2
Saya pikir Anda mungkin hanya meraba-raba sifat bahasa yang diketik secara dinamis. Anda harus membiasakan diri dengan pola pikir bahwa banyak kesalahan akan terjadi saat runtime alih-alih waktu kompilasi. Jika Anda merasa perlu memeriksa apakah setiap argumen adalah angka di setiap fungsi yang memasukkan angka, itu bisa menjadi beban (walaupun mungkin bermanfaat jika Anda mengirim lib dengan aman sebagai tujuan utama). Untuk skala apa pun, saya merasa penting untuk membiarkan fungsi gagal jika jenis yang salah dilewatkan. Alih-alih, fokus yang lebih produktif mungkin adalah membuat tes.
Di mana mungkin membantu untuk melakukan pemeriksaan ini untuk memastikan jenis sesuai dengan persyaratan antarmuka yang diperlukan (memeriksa untuk melihat apakah mereka memiliki metode yang diperlukan, misalnya) berada di fungsi Anda yang paling sentral dan banyak digunakan (yang dengan ketidakstabilan = 0 dengan metrik kopling eferen / aferen yang disediakan Martin). Itu harus menjadi target yang cukup kecil. Biasanya ada banyak fungsi lokal satu kali yang terisolasi dalam ruang lingkup - yang mungkin tidak memerlukan seperangkat pemeriksaan runtime yang komprehensif. Mereka tidak mengumpulkan banyak kompleksitas.
Alihkan ke Tipe Script. Ini masih diketik bebek, tetapi mendukung pengetikan statis untuk mendeteksi banyak kesalahan pada waktu kompilasi.
CodesInChaos
2
Anda telah menemukan satu masalah terbesar mengetik bebek: kekuatannya berasal dari kelemahannya. Jika Anda ingin melakukan JavaScript berorientasi objek, Anda hanya harus hidup dengan kesalahan run-time, dan berharap tes unit Anda menemukannya segera setelah Anda membuatnya :-(
Ross Patterson
@RossPatterson Masalah OPs adalah dengan pengetikan dinamis, bukan dengan pengetikan bebek. TypeScript dan Go keduanya diketik bebek, namun menghindari masalah OP. Masalah dengan mengetik bebek berbeda, yaitu bahwa Anda dapat memiliki anggota yang lulus tes bebek tetapi tidak memenuhi kontrak yang Anda harapkan.
CodesInChaos

Jawaban:

11

Bagaimana Anda menggunakan bebek mengetik dalam javascript tanpa selalu memeriksa properti dan metode?

Sederhana: jangan selalu memeriksa properti dan metode.

Di Ruby, apa yang Anda panggil disebut "mengetik ayam". Dalam bahasa yang diketik secara dinamis, Anda hanya percaya bahwa penelepon memberikan Anda objek yang cocok. Adalah tugas si penelepon untuk menghormati sisi kontraknya.

Saya tahu javascript menggunakan mengetik bebek dan pada awalnya saya pikir ini akan membuat polimorfisme mudah dibandingkan dengan bahasa yang sangat diketik seperti C #.

Anda membingungkan banyak poros ortogonal untuk mengetik di sini. Ada empat sumbu ortogonal untuk mengetik:

  • Kapan : pengetikan dinamis (tipe tidak diketahui dan diperiksa sampai runtime) vs. pengetikan statis (tipe diketahui dan diperiksa sebelum runtime)
  • Apa : pengetikan bebek (tipe berdasarkan perilaku ), pengetikan struktural (tipe berdasarkan pada struktur ), dan pengetikan nominal (tipe berdasarkan nama )
  • Bisakah kamu melihat mereka? pengetikan eksplisit (tipe harus dianotasi secara eksplisit) vs. pengetikan implisit (tipe disimpulkan)
  • pengetikan kuat vs pengetikan lemah - Anda mungkin telah memperhatikan bahwa saya tidak memberikan judul yang menarik atau penjelasan dalam tanda kurung, itu karena tidak seperti tujuh istilah di atas, yang masing-masing memiliki satu definisi akurat yang diterima secara universal, kedua istilah ini memiliki sekitar selusin definisi samar semi-banyak digunakan yang saling bertentangan; idealnya Anda harus menghindari istilah-istilah ini sama sekali, dan jika Anda harus menggunakannya, tentukan dengan tepat terlebih dahulu

Karena Anda menyebutkan C #: sebagian besar diketik secara statis, tetapi mendukung pengetikan dinamis melalui jenis dynamicitu, sebagian besar diketik secara nominal, tetapi tipe anonim menggunakan pengetikan struktural, dan pola sintaksis (seperti sintaksis pemahaman kueri LINQ) dapat diperdebatkan sebagai bebek -typed atau diketik secara struktural, sebagian besar diketik secara eksplisit tetapi mendukung pengetikan implisit untuk argumen tipe umum dan variabel lokal (walaupun case variabel lokal agak aneh dibandingkan dengan kebanyakan bahasa lain, karena Anda tidak bisa meninggalkan tipenya saja, Anda harus berikan tipe pseudo eksplisitvar, dengan kata lain, jika Anda menginginkan tipe implisit, Anda harus mengatakannya secara eksplisit). Apakah C # diketik dengan kuat atau lemah adalah masalah definisi dua istilah yang Anda gunakan, bagaimanapun, perhatikan bahwa mungkin ada banyak kesalahan tipe runtime di C #, terutama karena kovarians array yang tidak aman.

Saya tahu saya tidak bisa memeriksa, tetapi melacak kesalahan waktu javascript dapat menjadi mimpi buruk karena tidak selalu terjadi di mana kesalahan sebenarnya terjadi dalam kode.

Debugging bukanlah keterampilan yang mudah dipelajari. Namun, ada teknik untuk memudahkan debugging, misalnya Saff Squeeze adalah teknik yang dijelaskan oleh Kent Beck yang menggunakan tes dan refactoring untuk debugging:

Hit 'em High, Hit' em Low :

Pengujian Regresi dan Squeeze Saff

Kent Beck, Institut Three Rivers

Abstrak: Untuk mengisolasi cacat secara efektif, mulailah dengan tes tingkat sistem dan secara bertahap sebaris dan pangkas sampai Anda memiliki tes sekecil mungkin yang menunjukkan cacat.

Jörg W Mittag
sumber
Tautan hit high hit em low itu mendapatkan http 500 untuk saya, dengan "Halaman tidak lagi tersedia" sebagai pesan yang berorientasi manusia.
joshp
Domain threeriversinstitute.org tampaknya telah ditinggalkan.
Bart van Ingen Schenau
Ah, sial. Dan itu bahkan tidak diarsipkan di Mesin WayBack .
Jörg W Mittag
Bagaimana penelepon seharusnya menghormati sisi kontrak mereka? Sepertinya tidak ada cara untuk berkomunikasi (dalam kode) parameter apa yang seharusnya. Setiap fungsi adalah dari bentuk fungsi fname (objParam, objParam, ...). Apakah ini berarti bahasa seperti javascript sepenuhnya bergantung pada dokumentasi eksternal untuk mengkomunikasikan penggunaan?
Legiun
@Legion: dokumentasi, penamaan yang baik, akal sehat, tes sebagai spesifikasi perilaku, membaca kode sumber, apa saja. Perhatikan bahwa ini sebenarnya tidak jauh berbeda dari sistem tipe yang lebih lemah seperti C # atau Java: Misalnya arti dari nilai pengembalian IComparer<T>.Compare(T, T)hanya jelas dari dokumentasi, bukan jenisnya. Dan di mana dalam jenis java.util.Collections.binarySearch(java.util.List<T>)apakah dikatakan bahwa ...
Jörg W Mittag
1

Saya tahu saya tidak bisa memeriksa, tetapi melacak kesalahan waktu javascript dapat menjadi mimpi buruk karena tidak selalu terjadi di mana kesalahan sebenarnya terjadi dalam kode.

Memang, praktik tipikal adalah tidak memeriksa. Dan, ya, ini berarti Anda akan mendapatkan kesalahan javascript yang dilaporkan di tempat lain dari masalah sebenarnya. Namun dalam praktiknya, saya tidak menemukan ini menjadi masalah besar.

Ketika bekerja di javascript, saya terus menguji apa yang saya tulis. Pada sebagian besar kode, saya memiliki unit test yang berjalan secara otomatis setiap kali saya menyimpan editor saya. Ketika sesuatu yang tidak terduga terjadi, saya segera tahu. Saya memiliki area kode yang sangat kecil di mana saya mungkin melakukan kesalahan, karena hampir selalu hal terakhir yang saya sentuh yang memiliki kesalahan.

Ketika saya mendapatkan kesalahan runtime, saya setidaknya punya jejak stack, dan dalam kasus kesalahan di browser saya punya kemampuan untuk pergi ke tingkat jejak stack dan memeriksa variabel. Biasanya mudah untuk melacak kembali dari mana nilai buruk berasal, dan dengan demikian melacaknya kembali ke masalah semula.

Jika Anda seperti saya ketika saya menulis terutama dalam bahasa yang diketik secara statis, saya menulis blok kode yang lebih besar sebelum pengujian dan saya tidak memiliki praktik melacak nilai dari mana asalnya. Pemrograman dalam bahasa seperti javascript berbeda, Anda harus menggunakan keterampilan yang berbeda. Saya menduga pemrograman seperti itu tampaknya jauh lebih sulit, karena itu bukan keterampilan yang telah Anda kembangkan bekerja dalam bahasa lain seperti C #.

Karena itu, saya pikir ada banyak yang bisa dikatakan untuk tipe eksplisit. Mereka bagus untuk dokumentasi dan menangkap kesalahan lebih awal. Saya pikir di masa depan kita akan melihat peningkatan adopsi hal-hal seperti Flow dan Typecript yang menambahkan memeriksa jenis statis ke javascript.

Winston Ewert
sumber
0

Saya pikir Anda melakukan hal yang benar, Anda hanya perlu menemukan gaya yang akan lebih menyenangkan mata Anda. Berikut ini beberapa ide:

  • Alih-alih if(myObj.hasSomeProperty())Anda bisa menggunakan if( myobj.prop !== undefined ). Ini, BTW hanya akan berfungsi dalam mode non-ketat, dalam mode ketat yang harus Anda gunakan if( typeof myobj.prop !== 'undefined' ).

  • Anda dapat menurunkan beberapa pengecekan tipe ke validator terpisah. Ini memiliki manfaat untuk dapat melewati validasi setelah antarmuka matang, misalnya mulai dari if( is_valid( myobject ))mana .is_validif( !DEBUG ) return true;

  • Terkadang masuk akal untuk mengkloning input ke dalam bentuk kanonik, dalam hal ini Anda dapat mengumpulkan berbagai target validasi ke dalam fungsi / objek kloning. Untuk exmaple, di my_data = Data( myobj, otherstuff )dalam Datakonstruktor bisa nyaman menjalankan semua berbagai validasi di tempat yang sentral.

  • Anda bisa menggunakan beberapa pustaka yang akan (dengan kinerja tinggi) merampingkan validasi tipe Anda menjadi sesuatu yang lebih elegan. Bahkan jika Anda tidak akan mengambil rute ini dalam jangka panjang, Anda mungkin merasa nyaman untuk membawa Anda dengan lancar ke gaya Anda sendiri. Beberapa contoh termasuk xtype.js , ketik-cek , validator.js , dll.

avnr
sumber