Perhatikan bahwa saya mendasarkan semua argumen saya pada kasus penggunaan dunia nyata. Argumen balasan yang tidak dapat didukung dengan contoh penggunaan dalam aplikasi yang nyata, lengkap, menarik, bermanfaat tidak valid. Saya telah melihat "demo bahasa" kecil yang dimiliki semua orang, saya telah melihat posting blog yang merinci bagaimana prototipe dan pengetikan dinamis membuat beberapa contoh kecil yang sepele beberapa baris lebih pendek daripada di C #, tetapi itu tidak relevan untuk masalah Anda mengalami penulisan
kode nyata daripada mikro-demo dan mainan. Jadi, inilah keluhan saya dengan JS:
a) Sihir 'ini'. Ini dia, kecuali kalau ini dia. JavaScript mendorong Anda untuk menggunakan fungsi anonim di semua tempat, kecuali mereka selalu berakhir dengan konteks yang tepat untuk variabel 'ini', jadi Anda akhirnya memiliki kode konyol seperti "var _ini = ini" di semua tempat dan kemudian menggunakannya di dalam panggilan balik Anda atau fungsi lainnya. Beberapa hari saya bersumpah bahwa jumlah fungsi yang saya tulis yang tidak menggunakan nama 'ini' yang diganti sebenarnya lebih kecil daripada jumlah yang melakukannya.
b) 1 + "1" - 1 = 10. Juga, "1" + 0 = "10". Ya, ini sebenarnya telah menyebabkan bug untuk aplikasi kami, di mana data yang diharapkan berupa angka dimuat dari file JSON sebagai string karena bug di aplikasi lain, dan hasilnya tidak baik. Semua kode pemuatan kami harus diperbarui untuk menambahkan satu ton konversi jenis di semua tempat. Ketika saya membutuhkan sesuatu untuk menjadi nomor, saya benar-benar sangat ingin nomor itu, bukan string atau objek atau null atau apa pun. Lua, yang sangat mirip dengan JavaScript dalam banyak hal, memperbaiki masalah ini dengan tidak cukup terbelakang untuk menggunakan operator yang sama untuk penambahan dan penggabungan string.
c) Global oleh variabel default. Jadi, bahkan jika Anda mengambil argumen bahwa pengetikan dinamis hanya "lebih mudah" karena Anda tidak harus berpikir tentang deklarasi variabel, JavaScript membuang argumen itu ke luar jendela dengan membuat Anda meletakkan 'var' di depan pengidentifikasi baru di semua tempat . Dan kemudian diam-diam sekrup Anda jika Anda lupa.
d) Prototipe, bukan kelas. Ada sangat sedikit aplikasi JavaScript dunia nyata berskala besar yang tidak menggunakan sistem kelas mereka sendiri untuk mengatasi ketidakgunaan yang tidak terpisahkan dari prototipe dalam arsitektur aplikasi besar. Aplikasi-aplikasi yang sama menggunakan minimal prototipe untuk memperluas tipe JavaScript dasar, dan hanya karena JS dirancang dengan buruk sehingga bahkan dua tipe built-in yang menarik disertai dengan kekurangan setengah fitur yang Anda harapkan dimiliki.
e) Ketidakmampuan untuk membuat jenis pass-by-value. Ini adalah masalah yang sering terjadi di hampir semua bahasa selain dari C ++ / D, sebenarnya. Bagi mereka yang menggunakan JavaScript untuk menulis aplikasi WebGL, lihat semua pustaka aljabar linier untuk JavaScript. Dalam aplikasi 3D, Anda hampir sering menggunakan vektor daripada skalar. Bayangkan jika setiap bilangan bulat di aplikasi Anda dilewatkan dengan referensi, sehingga "a = 1; b = a; b ++" membuat a dan b sama dengan 2. Setiap vektor komponen kecil tiga adalah objek lengkap yang lengkap. Mereka dilewatkan dengan referensi (sumber hampir setengah bug di game WebGL kami sejauh ini, pada kenyataannya). Mereka ada dalam jumlah besar, dialokasikan dengan tumpukan, dan pengumpulan sampah, yang memberikan tekanan besar pada GC yang dapat dan memang mengakibatkan GC berhenti bahkan di game WebGL yang sederhana, kecuali pengembang melompat melalui lingkaran rumit yang rumit untuk menghindari membuat vektor baru di semua tempat yang logis untuk membuat vektor baru. Anda tidak dapat memiliki operator kelebihan, sehingga Anda memiliki ekspresi yang sangat besar dan jelek untuk melakukan operasi dasar. Mengakses komponen individual lambat. Objek tidak secara bawaan dikemas dan karenanya sangat lambat untuk mendorong ke buffer vertex, kecuali jika Anda menerapkannya sebagai contoh Float32Array, yang membingungkan omong kosong dari pengoptimal dari kedua V8 dan SpiderMonkey saat ini. Apakah saya menyebutkan mereka lulus dengan referensi? Mengakses komponen individual lambat. Objek tidak secara bawaan dikemas dan karenanya sangat lambat untuk mendorong ke buffer vertex, kecuali jika Anda menerapkannya sebagai contoh Float32Array, yang membingungkan omong kosong dari pengoptimal dari kedua V8 dan SpiderMonkey saat ini. Apakah saya menyebutkan mereka lulus dengan referensi? Mengakses komponen individual lambat. Objek tidak secara bawaan dikemas dan karenanya sangat lambat untuk mendorong ke buffer vertex, kecuali jika Anda menerapkannya sebagai contoh Float32Array, yang membingungkan omong kosong dari pengoptimal dari kedua V8 dan SpiderMonkey saat ini. Apakah saya menyebutkan mereka lulus dengan referensi?
f) Tidak ada built-in termasuk atau memerlukan fungsionalitas. Serius, diam. Perpustakaan pihak ketiga ada tetapi hampir semua dari mereka memiliki semacam bug atau yang lain, tidak sedikit di antaranya merupakan masalah cache yang membingungkan di setidaknya Chrome yang membuat pengembangan aktual menjadi masalah di pantat.
g) Pengetikan dinamis. Ya, saya bersedia memulai argumen itu. Anda mulai memperhatikannya paling banyak saat Anda berhenti menulis aplikasi Web kecil atau halaman Web dan mulai menulis aplikasi besar di mana Anda sebenarnya memiliki data yang bertahan lebih dari satu klik mouse atau siklus permintaan / respons: tambahkan jenis objek yang salah ke suatu Array untuk diproses kemudian dan mendapatkan crash kemudian dari metode yang hilang atau anggota dalam sedikit kode yang sama sekali berbeda dari tempat kesalahan sebenarnya. Waktu yang menyenangkan. Ya, Java membuat pengetikan statis tampak jahat. Tidak, Java / C # / C ++ bukan satu-satunya cara untuk melakukan pengetikan statis. Ketik inferensi, pengikatan antarmuka implisit, dll. Memberi Anda semua keuntungan "mudah ditangani dan tidak banyak penekanan tombol" dari pengetikan dinamis tanpa semua bug. Bahasa Web paling populer kedua - ActionScript 3 - diketik secara statis, pada kenyataannya, meskipun identik dengan JS / ECMAScript. Selain itu, saya mendapatkan lebih banyak crash dari aplikasi Python di desktop Fedora saya daripada yang saya lakukan dari aplikasi C / C ++ (sebenarnya, tidak ada aplikasi C / C ++ di desktop crash saya, sekarang saya memikirkannya). Pengecualian anggota yang hilang == jauh lebih mudah untuk mengembangkan dan memelihara aplikasi, bukan?
h) Kecepatan. Ya, telah ada sejumlah upaya yang sangat besar oleh sejumlah besar pengembang yang sangat buruk dimasukkan ke dalam runtime bahasa untuk membuat JS hampir setengah dari kompiler C kelas rendah yang dapat ditulis oleh satu perguruan tinggi Junior dalam beberapa bulan. Dan LuaJIT berada di kapal yang sama dengan JS dalam hal keterbatasan bahasa mendasar tetapi tetap berhasil lebih baik daripada setiap implementasi JavaScript. Orang-orang yang tidak mengerti apa yang sebenarnya dilakukan oleh semua optimasi JS di V8ingin mengklaim JS dapat melakukan hal-hal luar biasa dengan bijaksana, tetapi kenyataannya adalah semua optimasi itu pada dasarnya hanya "berusaha sangat keras untuk menganalisis kode untuk mengetahui jenis variabel dan kemudian mengompilasinya seperti yang agak terbelakang secara statis-diketik. kompiler bahasa akan melakukannya. " Oh, dan ada tracing, tapi kemudian tracing juga berfungsi pada bahasa yang diketik secara statis (dan bekerja lebih baik karena kurangnya kebutuhan untuk tipe penjaga di kode mesin yang dihasilkan). Tidak ada satu pun dari optimasi whizbang yang ditemukan oleh atau untuk JS, pada kenyataannya; sebagian besar diambil dari penelitian JVM (Jawa jahat!) atau bahasa OOP klasik (prototipe mengagumkan!).
i) Tidak mungkin IntelliSense. Ingin melihat metode apa yang ada pada variabel yang Anda dapatkan di sana pada baris 187 dari foo.js di editor teks Anda? Sangat buruk. Telusuri kode tersebut sampai Anda mengetahui di mana kode itu diinisialisasi, kemudian telusuri kode untuk mengetahui apa yang ada pada prototipe-nya. Dan kemudian berharap tidak ada kode yang secara dinamis mengubah prototipe di belakang Anda. Faktanya, jalankan saja di browser dan atur breakpoints, karena menemukan sesuatu yang berguna tentang nilai dengan cara lain pada dasarnya tidak mungkin untuk basis kode apa pun yang lebih besar dari situs toy_web_app.html yang digunakan para pembela JavaScript untuk memuliakan kemudahan dan kesederhanaan JavaScript. Beberapa editor kode berusaha sangat keras untuk berbuat lebih baik, dan hampir agak berhasil untuk kasus yang sangat sederhana, kadang-kadang, sekali.
j) Tidak ada keuntungan. JavaScript bahkan tidak istimewa dibandingkan dengan bahasa yang diketik secara dinamis lainnya. Itu tidak mampu melakukan sesuatu yang menarik sama sekali yang tidak dapat juga dilakukan oleh Lua, Python, Ruby, dll bahasa. JS tidak memiliki sisi positifnya dibandingkan dengan bahasa lain yang umumnya tersedia. Oh, kecuali itu berjalan secara native di browser Web tanpa plugin. Yang merupakan satu-satunya alasan di dunia mengapa ini sangat populer. Bahkan, itu satu-satunya alasan acara itu ada. Jika seseorang 10 tahun yang lalu baru saja berpikir, "heck, mari kita letakkan bahasa yang dirancang dengan baik dan mapan ke dalam peramban kami dan minta orang lain untuk melakukan hal yang sama alih-alih membuat semua orang menggunakan peretasan kecil konyol yang dibuat NetScape ini dengan , "Web akan terlihat jauh berbeda (lebih baik) hari ini. Bayangkan saja masa depan jika Chrome menjatuhkan Python ke Chrome sebagai bahasa yang didukung. Atau sebenarnya, bayangkan ini: Google memasukkan C / C ++ ke Chrome sebagai bahasa yang didukung (http://code.google.com/p/nativeclient/).