Apakah fakta bahwa penutupan fungsi referensi-sendiri anonim begitu menonjol dalam JavaScript menunjukkan bahwa JavaScript adalah spesifikasi yang tidak lengkap? Kami melihat begitu banyak:
(function () { /* do cool stuff */ })();
dan saya kira semuanya adalah masalah selera, tetapi apakah ini tidak terlihat seperti kludge, padahal yang Anda inginkan adalah namespace pribadi? Tidak bisakah JavaScript mengimplementasikan paket dan kelas yang tepat?
Bandingkan dengan ActionScript 3, juga berdasarkan ECMAScript, di mana Anda dapatkan
package com.tomauger {
import bar;
class Foo {
public function Foo(){
// etc...
}
public function show(){
// show stuff
}
public function hide(){
// hide stuff
}
// etc...
}
}
Kontras dengan konvolusi yang kami lakukan dalam JavaScript (ini, dari dokumentasi pembuat plugin jQuery ):
(function( $ ){
var methods = {
init : function( options ) { // THIS },
show : function( ) { // IS },
hide : function( ) { // GOOD },
update : function( content ) { // !!! }
};
$.fn.tooltip = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
Saya menghargai bahwa pertanyaan ini dapat dengan mudah berubah menjadi kata-kata kasar tentang preferensi dan gaya pemrograman, tapi saya sebenarnya sangat ingin mendengar bagaimana perasaan Anda para programmer berpengalaman tentang hal ini dan apakah itu terasa alami, seperti mempelajari berbagai keanehan dari bahasa baru, atau kludgy , seperti solusi untuk beberapa komponen bahasa pemrograman dasar yang tidak diimplementasikan?
sumber
Jawaban:
Sebagian besar komentar menentang mitos bahwa "prototipe adalah kelas orang miskin", jadi saya hanya akan mengulangi bahwa OO berbasis prototipe tidak kalah dengan OO berbasis kelas.
Titik lain "sebuah kludge ketika semua yang Anda inginkan adalah namespace pribadi". Anda mungkin terkejut mengetahui bahwa Skema menggunakan kludge yang sama persis untuk mendefinisikan cakupan. Itu tidak berhenti dari menjadi contoh dasar dari pelingkupan leksikal yang dilakukan dengan baik.
Tentu saja, dalam Skema, 'kludge' tersembunyi di balik makro ....
sumber
Pertama, beberapa hal:
Cara lain untuk melihat JavaScript adalah 1 juta dan 1 hal yang dapat Anda lakukan dengan fungsi sebagai konstruk. Semuanya ada di sana jika Anda mencarinya. Hanya saja tidak pernah jauh dari suatu fungsi.
Pengaya plug-in jQuery itu mengerikan. Saya tidak tahu mengapa mereka menganjurkan itu. $ extension harus berupa barang-barang yang umum digunakan yang $ sudah memiliki metode yang cukup baik tidak membangun-saya-a-widget lengkap. Ini adalah alat normalisasi DOM-API. Penggunaannya paling baik dimakamkan di dalam objek Anda sendiri. Saya tidak melihat daya tarik untuk menggunakannya sebagai repositori perpustakaan UI lengkap.
Paket di Web Sisi Klien Tidak Berguna
Yang secara pribadi tidak saya sukai tentang paket di web sisi klien adalah bahwa pada dasarnya kita akan berpura-pura melakukan sesuatu yang sebenarnya tidak kita lakukan. Dalam sebuah postingan .NET webforms dan sekumpulan hal-hal mengerikan yang tidak pernah di-pan-out-dari-teman-teman kita di Java, saya lebih suka memikirkan sebongkah HTML dengan sumber daya tertaut seperti apa sebenarnya. dan tidak mencoba menenangkan pengembang aplikasi OS yang tahan terhadap hal baru dengan berpura-pura itu sesuatu yang lain. Di JS di web sisi klien, tidak ada yang "diimpor" kecuali melakukan sesuatu yang buruk dengan Ajax yang beroperasi dalam ketidaktahuan caching peramban, yang ya, banyak yang telah coba lakukan. Yang penting bagi browser adalah bahwa itu dimuat dan ditafsirkan atau tidak. Kami tidak memiliki lebih banyak kode yang tersimpan di klien di suatu tempat yang tersedia untuk digunakan "untuk berjaga-jaga" untuk alasan yang bagus. # 1 adalah bahwa saya baru saja menggambarkan dependensi plug-in dan plug-in browser untuk aplikasi web karena sebuah fenomena belum berjalan dengan baik. Kami ingin web sekarang. Tidak setelah Adobe atau Sun selesai memperbarui ketiga kalinya minggu ini.
Bahasa Memiliki Apa yang Dibutuhkan untuk Struktur
Objek JS sangat bisa berubah. Kami dapat memiliki pohon percabangan ruang nama pada tingkat apa pun yang kami rasa berguna untuk melakukannya dan itu sangat mudah dilakukan. Tapi ya, untuk apa pun yang dapat digunakan kembali, Anda harus tetap menggunakan root dari perpustakaan mana pun di ruang global. Lagipula semua dependensi terhubung dan dimuat pada saat yang sama, jadi apa gunanya melakukan hal lain? Inti dari menghindari namespace global bukanlah sesuatu yang buruk. Terlalu banyak hal yang buruk karena Anda berisiko tabrakan namespace atau menimpa fitur bahasa inti secara tidak sengaja.
Hanya Karena Populer Tidak Berarti Kita Melakukannya Dengan Benar
Sekarang ketika Anda melihat ini di seluruh aplikasi web sisi klien:
Masalahnya bukanlah kita kekurangan alat untuk membuat struktur aplikasi, masalahnya adalah orang tidak menilai struktur. Untuk 2-3 halaman sekali pakai situs pembuangan sementara di agensi desain, saya tidak punya masalah dengan itu. Yang menjadi jelek adalah ketika Anda harus membangun sesuatu yang dapat dipelihara dan terbaca serta mudah dimodifikasi.
Tetapi ketika Anda sampai ke tempat di mana saatnya untuk hanya menerapkan semua benda dan pabrik yang dapat digunakan kembali dan mungkin satu atau dua vars sementara baru dapat menyusup ke dalam proses itu, itu adalah kenyamanan.
Tetapi Ada Implementasi JS Dengan Paket / Modul
Perlu diingat bahwa di Node.js, di mana hal-hal seperti itu jauh lebih masuk akal, mereka memiliki modul. JS, dengan asumsi kita dapat menghindari uber-config-hell yang mengganggu bahasa lain, adalah satu-satunya hal dalam persamaan dan setiap file yang dieksekusi adalah ruang lingkupnya sendiri yang terisolasi. Tetapi pada halaman web, menautkan file js sendiri merupakan pernyataan impor. Melakukan lebih banyak impor dengan cepat hanya membuang-buang waktu dan sumber daya karena mendapatkan sumber daya membutuhkan lebih banyak upaya daripada hanya menambahkan tautan ke file karena Anda membutuhkannya mengetahui mereka akan di-cache di browser jika halaman lain membutuhkannya lagi. Jadi sedang mencoba untuk membagi ruang global dengan melakukan apa pun selain membuat pabrik objek adaptor seperti jQuery atau objek yang lebih tradisional yang mencakup sebagian besar tugas dalam domain tertentu sambil menempati satu tempat di global. Sana'http://wiki.ecmascript.org/doku.php?id=harmony:modules
Jadi tidak, tidak ada yang salah dengan auto-invokers digunakan untuk menghindari polusi namespace global ketika ada alasan yang baik untuk menggunakan hal-hal seperti itu (lebih sering daripada tidak ada). Dan kami memiliki properti setara pribadi yang persisten di objek kami (cukup tentukan var di konstruktor dan jangan memaparkannya sebagai properti).
Fakta bahwa kita BISA melakukan hal-hal seperti itu, sungguh luar biasa. Penggunaan yang berat adalah tanda bahwa pengembang JS mungkin masih jatuh tempo, tetapi itu bukan lubang yang menganga dalam bahasa bagi siapa pun yang tidak mencoba memaksakan paradigma ke web sisi klien yang tidak masuk akal di sini.
sumber
Hal lain yang Anda lewatkan adalah javscript harus kompatibel. Jika Anda mencoba mengenalkan sintaksis paket, itu bisa merusak web dengan beberapa cara gila. Itu akan buruk! Doug Crockford telah membicarakan hal ini di berbagai titik dan mengapa upaya untuk menambahkannya gagal.
sumber
Ya, itu adalah kludge.
Banyak orang mengatakan bahwa "prototipe tidak kalah dengan kelas". Saya tidak setuju, tapi itu masalah pilihan. Tapi itu bahkan bukan masalah sebenarnya dengan JavaScript - masalahnya adalah bahwa itu awalnya dirancang sebagai bahasa scripting cepat dan kotor untuk membuat hal-hal seperti tombol animasi. Kembali di pertengahan 90-an tidak ada yang pernah berpikir bahwa JavaScript akan diminta untuk melakukan beberapa hal gila yang sedang dilakukan sekarang.
sumber
Fungsi pemanggilan mandiri anonim lebih mirip dengan modul daripada ke kelas. Sangat menjengkelkan bahwa standar untuk javascript dijalankan di lingkup global. Panitia yang mengerjakan JS.next secara serius mempertimbangkan untuk menambahkan modul, sehingga Anda tidak memasukkan variabel lokal Anda ke dalam lingkup global. Untungnya, fungsi Javascript memiliki semantik yang nyaman sehingga kita dapat menggunakan fungsi anonim sebagai ruang lingkup pribadi dengan relatif mudah.
Saya tidak melihat bagaimana kelas benar-benar masuk ke dalam diskusi sama sekali, kecuali bahwa mereka adalah konstruksi pelingkupan tingkat atas dalam banyak bahasa. Modul / paket / tolong-beri-aku-lingkup-lokal-jadi-aku-jangan-tinggalkan-variabel-saya-dalam-lingkungan-global yang lebih baik akan sangat menyenangkan untuk dimiliki.
sumber
Anda mungkin ingin melihat ExtJS 3 dan 4 di mana mereka telah berhasil mengimplementasikan ruang nama dengan cukup baik.
- ditambahkan setelah -1
Maksud saya di sini adalah, mungkin untuk menyembunyikan semua 'konvolusi' ini dan masih memiliki kode yang cukup ramah seperti:
sumber