Pola modul JavaScript dengan contoh [ditutup]

138

Saya tidak dapat menemukan contoh yang dapat diakses yang menunjukkan bagaimana dua (atau lebih) modul berbeda dihubungkan untuk bekerja bersama.

Jadi, saya ingin bertanya apakah ada yang punya waktu untuk menulis contoh yang menjelaskan bagaimana modul bekerja sama.

Srle
sumber
Ini semua telah berubah dalam empat tahun terakhir, tetapi berkat moderasi berlebihan yang bersemangat, info usang ini akan bertahan selamanya . Ini halaman MDN tentang modulel ES6.
bbsimonbb

Jawaban:

259

Untuk mendekati pola desain Modular, Anda perlu memahami konsep ini terlebih dahulu:

Ekspresi Fungsi (IIFE) yang Segera Diminta:

(function() {
      // Your code goes here 
}());

Ada dua cara untuk menggunakan fungsi tersebut. 1. Deklarasi fungsi 2. Ekspresi fungsi.

Berikut menggunakan ekspresi fungsi.

Apa itu namespace? Sekarang jika kita menambahkan namespace ke bagian kode di atas

var anoyn = (function() {
}());

Apa closure di JS?

Artinya jika kita mendeklarasikan fungsi apa pun dengan lingkup variabel apa pun / di dalam fungsi lain (di JS kita dapat mendeklarasikan fungsi di dalam fungsi lain!) Maka itu akan selalu menghitung ruang lingkup fungsi itu. Artinya, variabel apa pun di fungsi luar akan selalu dibaca. Itu tidak akan membaca variabel global (jika ada) dengan nama yang sama. Ini juga salah satu tujuan penggunaan pola desain modular untuk menghindari konflik penamaan.

var scope = "I am global";
function whatismyscope() {
    var scope = "I am just a local";
    function func() {return scope;}
    return func;
}
whatismyscope()()

Sekarang kita akan menerapkan tiga konsep yang saya sebutkan di atas untuk menentukan pola desain modular pertama kita:

var modularpattern = (function() {
    // your module code goes here
    var sum = 0 ;

    return {
        add:function() {
            sum = sum + 1;
            return sum;
        },
        reset:function() {
            return sum = 0;    
        }  
    }   
}());
alert(modularpattern.add());    // alerts: 1
alert(modularpattern.add());    // alerts: 2
alert(modularpattern.reset());  // alerts: 0

jsfiddle untuk kode di atas.

Tujuannya adalah untuk menyembunyikan aksesibilitas variabel dari dunia luar.

Semoga ini membantu. Semoga berhasil.

kta
sumber
apakah lebih baik menamai iife? untuk tujuan semantik dan pelacakan tumpukan yang lebih baik? apakah itu akan mengubah apa pun dalam kode?
Jeroen
2
Contoh pertama Anda (function() { /* Your code goes here */}());sebenarnya adalah IIFE (Ekspresi Fungsi Segera Memanggil), ok itu anonim karena tidak memiliki nama sehingga Anda bahkan mungkin ingin menyebutnya sebagai IIAFE (Segera Memanggil Ekspresi Fungsi Anonim) lihat lebih lanjut tentang IIFE di stackoverflow.com/questions/ 2421911 /…
Adrien Be
mengapa pernyataan pengembalian digunakan? jika kita menghilangkan return {} maka fungsi tambah dan setel ulang akan menjadi publik dan saya kira mereka bisa mengakses variabel lokal sum? Apakah saya benar?
Mou
contoh kedua Anda terlihat seperti objek atau saya tidak benar?
The Reason
4
Ini tidak menjawab pertanyaan OP. Ini adalah deskripsi pola modul, bukan contoh bagaimana beberapa modul dapat bekerja sama seperti yang diinginkan OP.
Erik Trautman
39

Saya sangat merekomendasikan siapa pun yang memasuki subjek ini untuk membaca buku gratis Addy Osmani:

"Mempelajari Pola Desain JavaScript".

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Buku ini sangat membantu saya ketika saya mulai menulis JavaScript yang lebih mudah dirawat dan saya masih menggunakannya sebagai referensi. Lihatlah implementasi pola modulnya yang berbeda, dia menjelaskannya dengan sangat baik.

Kode Novisiat
sumber
Saya juga merekomendasikan untuk membaca artikel saya tentang "Pola Modul Definitif" yang tidak tercakup dalam buku Addy Osmani: github.com/tfmontague/definitive-module-pattern
tfmontague
1
Bagaimana hal ini dibandingkan dengan "Pola JavaScript" oleh Stoyan Stefanov
JohnMerlino
4
Buku Stoyan jauh lebih komprehensif. Ini mencakup lebih dari sekedar pola tingkat tinggi tetapi juga berbicara lebih mendalam tentang praktik terbaik JS lainnya.
Kode Novisiat
1
ulasan tentang "Belajar Pola Desain JavaScript" amazon.com/product-reviews/1449331815
Adrien Be
3
ulasan tentang "Pola JavaScript" oleh Stoyan Stefanov amazon.com/product-reviews/0596806752 . Catatan: yang tampaknya jauh lebih baik daripada yang ada dari "Belajar Pola Desain JavaScript"
Adrien Be
18

Saya pikir saya akan memperluas jawaban di atas dengan berbicara tentang bagaimana Anda akan menyesuaikan modul menjadi sebuah aplikasi. Saya pernah membaca tentang ini di buku doug crockford tetapi karena baru mengenal javascript, semuanya masih agak misterius.

Saya berasal dari latar belakang ac # jadi telah menambahkan beberapa terminologi yang menurut saya berguna dari sana.

Html

Anda akan memiliki semacam file html tingkat atas. Ini membantu untuk menganggap ini sebagai file proyek Anda. Setiap file javascript yang Anda tambahkan ke proyek ingin masuk ke ini, sayangnya Anda tidak mendapatkan dukungan alat untuk ini (saya menggunakan IDEA).

Anda perlu menambahkan file ke proyek dengan tag skrip seperti ini:

        <script type="text/javascript" src="app/native/MasterFile.js" /></script>
        <script type="text/javascript" src="app/native/SomeComponent.js" /></script>

Tampaknya menciutkan tag menyebabkan hal-hal gagal - sementara itu terlihat seperti xml itu benar-benar sesuatu dengan aturan yang lebih gila!

File namespace

MasterFile.js

myAppNamespace = {};

itu dia. Ini hanya untuk menambahkan satu variabel global untuk kode kita yang tersisa. Anda juga bisa mendeklarasikan namespace bertingkat di sini (atau di file mereka sendiri).

Modul

SomeComponent.js

myAppNamespace.messageCounter= (function(){

    var privateState = 0;

    var incrementCount = function () {
        privateState += 1;
    };

    return function (message) {
        incrementCount();
        //TODO something with the message! 
    }
})();

Apa yang kita lakukan di sini adalah menetapkan fungsi penghitung pesan ke variabel dalam aplikasi kita. Ini adalah fungsi yang mengembalikan fungsi yang segera kita jalankan .

Konsep

Saya pikir itu membantu untuk memikirkan baris teratas di SomeComponent sebagai namespace tempat Anda mendeklarasikan sesuatu. Satu-satunya peringatan untuk ini adalah semua namespace Anda harus muncul di beberapa file lain terlebih dahulu - mereka hanyalah objek yang di-root oleh variabel aplikasi kita.

Saya hanya mengambil langkah kecil dengan ini saat ini (saya merefaktor beberapa javascript normal dari aplikasi extjs sehingga saya dapat mengujinya) tetapi tampaknya cukup bagus karena Anda dapat menentukan unit fungsional kecil sambil menghindari rawa 'ini ' .

Anda juga bisa menggunakan gaya ini untuk mendefinisikan konstruktor dengan mengembalikan fungsi yang mengembalikan objek dengan sekumpulan fungsi dan tidak langsung memanggilnya.

JonnyRaa
sumber
6

Di sini https://toddmotto.com/mastering-the-module-pattern Anda dapat menemukan pola yang dijelaskan secara menyeluruh. Saya akan menambahkan bahwa hal kedua tentang JavaScript modular adalah bagaimana menyusun kode Anda dalam banyak file. Banyak orang mungkin menyarankan Anda di sini untuk menggunakan AMD, namun saya dapat mengatakan dari pengalaman bahwa Anda akan berakhir di beberapa titik dengan respons halaman yang lambat karena banyak permintaan HTTP. Jalan keluarnya adalah pra-kompilasi modul JavaScript Anda (satu per file) menjadi satu file mengikuti standar CommonJS. Lihat contoh di sini http://dsheiko.github.io/cjsc/

Dmitry Sheiko
sumber
Semua implementasi AMD juga menyediakan prakompilasi ke dalam satu file.
I-Lin Kuo
1
Itu benar, tetapi file yang dioptimalkan yang dihasilkan membutuhkan pustaka loader (cukup periksa ulang dengan r.js v2.1.14), yang biasanya cukup berbobot. Segera setelah kami mengompilasi kode, kami tidak perlu menyelesaikan dependensi yang dimuat secara asinkron, kami tidak memerlukan library ini. Pertimbangkan saja: kami membungkus modul ke dalam AMD, itu berarti async. memuat, lalu kompilasi menjadi satu file (tidak ada lagi pemuatan terpisah), tetapi muat seluruh pustaka untuk mengatasinya (apa yang mubazir sekarang). Ini tidak terdengar sebagai cara yang optimal bagi saya. Mengapa AMD sama sekali ketika kita tidak memuat secara asinkron?
Dmitry Sheiko
almond.js menyediakan pemuat berbobot yang lebih kecil untuk kode produksi jadi daripada RequireJS, tetapi secara komparatif, manfaat kinerja tidak hanya membuat satu permintaan http jauh lebih besar daripada biaya penambahan kode pemuat ke modul, jadi meskipun kurang optimal, itu pada skala yang jauh lebih kecil. Pertanyaannya, menurut saya, harus dibalik - mengapa menganggap sinkronisitas ketika browser tidak? Saya sebenarnya berpendapat bahwa RequireJS dan CommonJS harus memiliki implementasi yang menjanjikan.
I-Lin Kuo
Kedua format tersebut merupakan jalur yang valid ke CommonJS Modules / 2.0 dan memberikan skalabilitas yang sama. Bagi saya - berurusan dengan CJS Modules / 1.1 (itulah yang saya maksud dengan CommonJS) jauh lebih mudah, kode terlihat lebih bersih.
Dmitry Sheiko
Saya telah menemukan manfaat AMD seperti: * dapat memuat lebih dari sekadar file JavaScript; * alias jalur; Nah, CommonJS Compiler memecahkan ini - ia memuat dependensi non-JavaScipt / JSON sebagai data dan dapat disediakan dengan konfigurasi build (termasuk alias). Satu-satunya kelemahan yang membutuhkan pembangunan. Tapi saat ini semua orang tetap membangun proyek untuk pra-prosesor CSS. Jadi ini hanya tentang menambahkan tugas tambahan untuk Grunt / Gulp ...
Dmitry Sheiko