Pemrograman modular adalah pola pemrograman JavaScript yang sangat umum. Secara umum dapat membuat kode lebih mudah dipahami, tetapi ada banyak praktik luar biasa yang tidak diketahui.
Basis
Mari kita pertama kali menguraikan beberapa pola modular sejak Eric Miraglia (pengembang YUI) pertama kali menerbitkan sebuah blog tiga tahun lalu menggambarkan pola modular. Jika Anda sudah sangat terbiasa dengan mode modular ini, Anda dapat melewatkan bagian ini secara langsung dan mulai membaca dari "Mode Lanjutan".
Penutupan anonim
Ini adalah struktur dasar yang memungkinkan segala hal, dan juga merupakan fitur terbaik dari JavaScript. Kami hanya akan membuat fungsi anonim dan menjalankannya segera. Semua kode akan berjalan dalam fungsi ini dan hidup dalam penutupan yang menyediakan privatisasi, yang cukup untuk memungkinkan variabel dalam penutupan ini untuk berjalan sepanjang umur aplikasi kita.
Salinan kode adalah sebagai berikut:
(fungsi () {
// ... semua vars dan fungsi hanya ada dalam lingkup ini
// masih mempertahankan akses ke semua global
} ());
Perhatikan braket terluar dari pasangan ini membungkus fungsi anonim. Karena karakteristik bahasa JavaScript, ini diperlukan untuk tanda kurung. Pernyataan yang dimulai dengan fungsi kata kunci dalam JS selalu dianggap sebagai deklaratif fungsi. Bungkus kode ini dalam tanda kurung untuk memberi tahu penerjemah bahwa ini adalah ekspresi fungsi.
Impor variabel global
JavaScript memiliki fitur yang disebut variabel global implisit. Tidak peduli di mana nama variabel digunakan, penerjemah akan menemukan pernyataan deklarasi var dari variabel secara terbalik sesuai dengan rantai lingkup. Jika pernyataan Deklarasi VAR tidak ditemukan, maka variabel ini akan dianggap sebagai variabel global. Jika variabel ini digunakan dalam pernyataan penugasan dan variabel tidak ada, variabel global akan dibuat. Ini berarti mudah digunakan atau membuat variabel global dalam penutupan anonim. Sayangnya, ini membuat kode tertulis sangat sulit untuk dipertahankan, karena untuk perasaan intuitif orang, tidak mungkin untuk mengatakan bahwa variabel -variabel itu global.
Untungnya, fungsi anonim kami memberikan solusi sederhana. Lulus saja variabel global sebagai parameter ke fungsi anonim kami, Anda bisa mendapatkan kode yang lebih jelas dan lebih cepat dari variabel global implisit. Inilah contohnya:
Salinan kode adalah sebagai berikut:
(function ($, yahoo) {
// sekarang memiliki akses ke global jQuery (sebagai $) dan yahoo dalam kode ini
} (jQuery, yahoo));
Ekspor Modul
Terkadang Anda tidak hanya ingin menggunakan variabel global, Anda juga ingin mendeklarasikannya untuk penggunaan berulang. Kita dapat melakukan ini dengan mudah dengan menyiapkannya - melalui nilai pengembalian fungsi anonim. Melakukan hal itu akan menyelesaikan model modular dasar, dan berikut ini akan menjadi contoh lengkap:
Salinan kode adalah sebagai berikut:
var module = (function () {
var my = {},
privatevariable = 1;
function privateMethod () {
// ...
}
my.moduleProperty = 1;
my.modulemethod = function () {
// ...
};
kembalikan saya;
} ());
Perhatikan bahwa kami telah mendeklarasikan modul global yang disebut modul, yang memiliki 2 properti publik: metode yang disebut module.modulemethod dan variabel yang disebut modul.moduleproperty. Selain itu, ia mempertahankan keadaan bawaan pribadi yang memanfaatkan penutupan fungsi anonim. Pada saat yang sama, kami dapat dengan mudah mengimpor variabel global yang diperlukan dan menggunakan pola modular ini seperti yang telah kami pelajari sebelumnya.
Mode lanjutan
Dasar yang dijelaskan pada bagian di atas sudah cukup untuk menangani banyak situasi, dan sekarang kita dapat lebih mengembangkan model modular ini untuk menciptakan struktur yang lebih kuat dan dapat diskalakan. Mari kita mulai dengan modul modul dan perkenalkan mode canggih ini satu per satu.
Mode Zoom
Seluruh modul harus menjadi batasan mode modular dalam satu file. Siapa pun yang terlibat dalam proyek besar akan memahami nilai pemisahan beberapa file dengan JS. Untungnya, kami memiliki implementasi yang hebat untuk memperkuat modul. Pertama, kami mengimpor modul, menambahkan properti ke dalamnya, dan akhirnya mengekspornya. Berikut adalah contoh - zoom in dari modul asli:
Salinan kode adalah sebagai berikut:
var module = (function (my) {
my.anothermethod = function () {
// Metode yang ditambahkan ...
};
kembalikan saya;
}(MODUL));
Kami menggunakan kata kunci VAR untuk memastikan konsistensi, meskipun tidak perlu di sini. Setelah kode ini dieksekusi, modul kami sudah memiliki metode publik baru yang disebut modul.anothermethod. File yang diperbesar ini juga akan mempertahankan status built-in pribadinya sendiri dan objek impor.
Mode Zoom Lebar
Contoh kami di atas mengharuskan modul inisialisasi kami untuk dieksekusi terlebih dahulu dan kemudian diamplifikasi modul untuk dieksekusi, dan tentu saja kadang -kadang ini mungkin tidak perlu diperlukan. Salah satu hal terbaik yang dapat dilakukan aplikasi JavaScript untuk meningkatkan kinerja adalah menjalankan skrip secara tidak sinkron. Kami dapat membuat modul multipart yang fleksibel dan memungkinkannya dimuat dalam urutan apa pun melalui mode zoom yang luas. Setiap file perlu diatur dalam struktur berikut:
Salinan kode adalah sebagai berikut:
var module = (function (my) {
// tambahkan kemampuan ...
kembalikan saya;
} (Modul || {}));
Dalam pola ini, ekspresi VAR membuatnya perlu. Perhatikan bahwa jika modul belum diinisialisasi, pernyataan impor ini akan membuat modul. Ini berarti Anda dapat menggunakan alat seperti LABJS untuk memuat semua file modul Anda secara paralel tanpa diblokir.
Mode pembesaran yang ketat
Mode yang sangat luas sangat bagus, tetapi juga akan menempatkan beberapa batasan pada modul Anda. Yang terpenting, Anda tidak dapat dengan aman menimpa sifat -sifat modul. Anda tidak dapat menggunakan properti dari file lain saat menginisialisasi (tetapi Anda dapat menggunakannya saat berjalan). Mode pembesaran yang ketat berisi urutan yang dimuat dan memungkinkan sifat utama. Berikut adalah contoh sederhana (zoom dalam modul asli kami):
Salinan kode adalah sebagai berikut:
var module = (function (my) {
var old_modulemethod = my.modulemethod;
my.modulemethod = function () {
// Metode override, memiliki akses ke lama melalui old_modulemethod ...
};
kembalikan saya;
}(MODUL));
Kami mengesampingkan implementasi modul.modulemethod dalam contoh di atas, tetapi bila diperlukan, kami dapat mempertahankan referensi ke metode asli.
Klon dan warisan
Salinan kode adalah sebagai berikut:
var module_two = (function (old) {
var my = {},
kunci;
untuk (kunci di lama) {
if (old.hasownproperty (key)) {
saya [key] = lama [kunci];
}
}
var super_modulemethod = old.modulemethod;
my.modulemethod = function () {
// Override Metode pada klon, akses ke super melalui super_modulemethod
};
kembalikan saya;
}(MODUL));
Model ini mungkin merupakan opsi yang paling tidak fleksibel. Itu membuat kode terlihat rapi, tetapi itu datang dengan biaya fleksibilitas. Seperti yang saya tulis di atas, jika suatu properti adalah objek atau fungsi, itu tidak akan disalin, tetapi akan menjadi referensi kedua untuk objek atau fungsi. Jika Anda memodifikasi salah satunya, Anda akan memodifikasi yang lain secara bersamaan (catatan penerjemah: karena mereka hanya satu!). Ini dapat diselesaikan dengan proses kloning rekursif, tetapi fungsi kloning mungkin tidak diselesaikan, mungkin dapat diselesaikan dengan eval. Oleh karena itu, saya memberi tahu metode ini dalam artikel ini hanya memperhitungkan integritas artikel.
Variabel pribadi lintas file
Ada batasan yang signifikan untuk membagi modul menjadi beberapa file: setiap file mempertahankan variabel privatnya sendiri dan tidak dapat mengakses variabel pribadi untuk file lain. Tapi masalah ini bisa diselesaikan. Berikut adalah contoh dari modul luas yang memelihara variabel pribadi di seluruh file:
Salinan kode adalah sebagai berikut:
var module = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || fungsi () {
hapus my._private;
hapus my._seal;
hapus my._unseal;
},
_unseal = my._unseal = my._unseal || fungsi () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// akses permanen ke _private, _seal, dan _unseal
kembalikan saya;
} (Modul || {}));
Semua file dapat mengatur properti pada variabel _private masing -masing, dan dipahami bahwa mereka dapat diakses oleh file lain. Setelah modul ini dimuat, aplikasi dapat memanggil modul._seal () untuk mencegah panggilan eksternal ke _private internal. Jika modul ini perlu disagih kembali, metode internal dalam file apa pun dapat menghubungi _unseal () sebelum memuat file baru, dan hubungi _seal () lagi setelah file baru dijalankan. Saya menggunakan pola ini di tempat kerja sekarang dan saya belum melihatnya di tempat lain. Saya pikir ini adalah model yang sangat berguna dan ada baiknya menulis artikel tentang model ini sendiri.
Submodules
Mode lanjutan terakhir kami jelas yang paling mudah. Ada banyak contoh yang sangat baik untuk membuat submodul. Ini seperti membuat modul normal:
Salinan kode adalah sebagai berikut:
Module.sub = (function () {
var my = {};
// ...
kembalikan saya;
} ());
Meskipun ini tampak sederhana, saya pikir perlu disebutkan di sini. Submodul memiliki semua keuntungan lanjutan dari modul umum, termasuk mode amplifikasi dan status privatisasi.
sebagai kesimpulan
Mode paling canggih dapat digabungkan untuk membuat mode yang lebih berguna. Jika saya benar -benar ingin merekomendasikan pola modular untuk merancang aplikasi yang kompleks, saya akan memilih untuk menggabungkan mode amplifikasi luas, variabel pribadi, dan submodul.
Saya belum mempertimbangkan kinerja mode -mode ini, tetapi saya lebih suka mengubah ini menjadi cara berpikir yang lebih sederhana: jika mode modular memiliki kinerja yang baik, itu dapat melakukan pekerjaan yang baik untuk meminimalkannya, membuat mengunduh file skrip ini lebih cepat. Menggunakan mode pembesaran luas memungkinkan unduhan paralel sederhana non-blocking, yang mempercepat unduhan. Waktu inisialisasi mungkin sedikit lebih lambat dari metode lain, tetapi layak setelah menimbang pro dan kontra. Selama impor variabel global akurat, kinerja runtime harus terpengaruh, dan juga dimungkinkan untuk mencapai kecepatan lari yang lebih cepat dalam submodul dengan memperpendek rantai referensi dengan variabel pribadi.
Sebagai kesimpulan, berikut adalah contoh modul anak secara dinamis memuat dirinya ke modul induknya (membuatnya jika modul induk tidak ada). Untuk kesederhanaan, saya menghapus variabel pribadi, dan tentu saja sangat mudah untuk menambahkan variabel pribadi. Pola pemrograman ini memungkinkan seluruh basis kode struktur hierarkis kompleks yang dimuat secara paralel melalui submodul.
Salinan kode adalah sebagai berikut:
var util = (fungsi (induk, $) {
var my = parent.AJAX = Parent.Ajax || {};
my.get = function (url, params, callback) {
// ok, jadi saya sedikit curang :)
mengembalikan $ .getjson (url, params, callback);
};
// dll...
orang tua yang kembali;
} (Util || {}, jQuery));
Artikel ini merangkum praktik terbaik saat ini dari "pemrograman modular JavaScript" dan menjelaskan cara mempraktikkannya. Meskipun ini bukan tutorial utama, Anda dapat memahaminya hanya dengan sedikit pemahaman tentang sintaks dasar JavaScript.