JavaScript modülü modeli ve örnek [kapalı]


136

İki (veya daha fazla) farklı modülün birlikte çalışmak için nasıl bağlandığını gösteren erişilebilir örnekler bulamıyorum.

Bu yüzden, modüllerin birlikte nasıl çalıştığını açıklayan bir örnek yazmak için zamana sahip olup olmadığını sormak istiyorum.


Tüm bunlar son dört yılda değişti, ancak gayretli aşırı moderasyon sayesinde, bu güncel olmayan bilgi sonsuza kadar dolacak . İşte ESN modüllerindeki MDN sayfası .
bbsimonbb

Yanıtlar:


256

Modüler tasarım modeline yaklaşmak için önce bu konsepti anlamanız gerekir:

Hemen Başlatılan İşlev İfadesi (IIFE):

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

İşlevleri kullanmanın iki yolu vardır. 1. İşlev bildirimi 2. İşlev ifadesi.

Burada fonksiyon ifadesi kullanılıyor.

İsim alanı nedir? Şimdi yukarıdaki kod parçasına ad alanını eklersek

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

JS'de kapatma nedir?

Bu, herhangi bir fonksiyonu herhangi bir değişken kapsamla / başka bir fonksiyonun içinde (JS'de başka bir fonksiyonun içinde bir fonksiyon ilan edebiliriz!) İlan edersek, o zaman o fonksiyon kapsamını her zaman sayacaktır. Bu, dış işlevdeki herhangi bir değişkenin her zaman okunacağı anlamına gelir. Aynı ada sahip genel değişkeni (varsa) okumaz. Bu aynı zamanda isimlendirme çatışmasından kaçınarak modüler tasarım deseni kullanma hedeflerinden biridir.

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

Şimdi ilk modüler tasarım modelimizi tanımlamak için yukarıda bahsettiğim bu üç kavramı uygulayacağız:

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

Yukarıdaki kod için jsfiddle.

Amaç değişken erişilebilirliği dış dünyadan gizlemek.

Bu yardımcı olur umarım. İyi şanslar.


iife adını vermek daha iyi olur mu? anlamsal amaçlar ve daha iyi yığın izleme için? koddaki herhangi bir şeyi değiştirir mi?
Jeroen

2
İlk örneğiniz (function() { /* Your code goes here */}());aslında bir IIFE (Hemen Fonksiyon İfadesini Çağırıyor), tamam anonim çünkü adı olmayan bir IIAFE (Hemen Anonim Fonksiyon İfadesini Çağırmak) olarak adlandırmak isteyebilirsiniz bile stackoverflow.com/questions/ 2421911 /…
Adrien

iade beyanı neden kullanıldı? dönüş {} atlarsak ekleme ve sıfırlama işlevi herkese açık olur ve sanırım yerel değişken toplamına erişebilir mi? haklı mıyım
Mou

ikinci örneğiniz bir nesneye benziyor ya da ben doğru değilim?
Sebep

4
Bu OP'nin sorusunu ele almıyor. Modül modelinin bir açıklaması, OP'nin istediği gibi birden fazla modülün birlikte nasıl çalışabileceğinin bir örneği değildir.
Erik Trautman

39

Bu konuya giren herkese Addy Osmani'nin ücretsiz kitabını okumasını tavsiye ederim:

Msgstr "JavaScript Tasarım Kalıplarını Öğrenme".

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

Bu kitap, daha sürdürülebilir bir JavaScript yazmaya başladığımda bana çok yardımcı oldu ve hala referans olarak kullanıyorum. Farklı modül modeli uygulamalarına bir göz atın, onları gerçekten iyi açıklıyor.


Ayrıca Addy Osmani'nin kitabında yer almayan "Kesin Modül Deseni" hakkındaki makalemi de okumanızı tavsiye ederim: github.com/tfmontague/definitive-module-pattern
tfmontague

1
Bu nasıl Stoyan Stefanov
JohnMerlino

4
Stoyan'ın kitabı çok daha kapsamlı. Üst düzey kalıplardan daha fazlasını kapsar, aynı zamanda diğer JS en iyi uygulamaları hakkında daha derinlemesine konuşur.
Kod Novitiate

1
"JavaScript Tasarım Desenlerini Öğrenme" yorumları amazon.com/product-reviews/1449331815
Adrien Be

3
Stoyan Stefanov tarafından yazılan "JavaScript Patterns" yorumları amazon.com/product-reviews/0596806752 . Not: "JavaScript Tasarım Desenlerini Öğrenme" den çok daha iyi görünüyor
Adrien

19

Modülleri bir uygulamaya nasıl sığdıracağınızdan bahsederek yukarıdaki cevabı genişleteceğimi düşündüm. Doug crockford kitapta bunu okurdum ama javascript için yeni olmak hala biraz gizemli oldu.

Ben ac # arka plan geliyor o yüzden yararlı buluyorum bazı terminoloji ekledik.

Html

Bazı üst düzey html dosyanız olacak. Bunu proje dosyanız olarak düşünmenize yardımcı olur. Projeye eklediğiniz her javascript dosyası buna girmek istiyor, maalesef bunun için araç desteği almıyorsunuz (IDEA kullanıyorum).

Bu gibi komut dosyası etiketleri ile projeye dosya eklemeniz gerekir:

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

Etiketleri daraltmak işlerin başarısız olmasına neden olur - xml gibi görünüyorken gerçekten daha çılgın kurallara sahip bir şey!

Ad alanı dosyası

MasterFile.js

myAppNamespace = {};

bu kadar. Bu, yalnızca kodumuzun geri kalanının yaşaması için tek bir global değişken eklemek içindir. Burada (veya kendi dosyalarında) iç içe geçmiş ad alanları da bildirebilirsiniz.

Modül (lar)

SomeComponent.js

myAppNamespace.messageCounter= (function(){

    var privateState = 0;

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

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

Burada yaptığımız şey, uygulamamızdaki bir değişkene bir mesaj sayacı işlevi atamaktır. Biz bir işlev geri döndüren bir fonksiyon hemen yürütmek .

Kavramlar

SomeComponent üst satırında bir şey bildirdiğiniz ad alanı olarak düşünmek için yardımcı olduğunu düşünüyorum. Bunun tek uyarısı, tüm ad alanlarınızın önce başka bir dosyada görünmesi gerektiğidir - bunlar sadece uygulama değişkenimiz tarafından köklenen nesnelerdir.

Ben şu anda bu sadece küçük adımlar attım (i test edebilirsiniz böylece bir extjs app bazı normal javascript yeniden düzenleme) ama 'bu quagmire kaçınarak küçük fonksiyonel birimleri tanımlamak gibi oldukça güzel görünüyor ' .

Bu stili ayrıca, işlevleri toplayan bir nesneyi döndüren ve hemen çağırmayarak bir işlev döndürerek yapıcıları tanımlamak için de kullanabilirsiniz.


6

Burada https://toddmotto.com/mastering-the-module-pattern şablonu ayrıntılı bir şekilde açıklanmıştır. Modüler JavaScript ile ilgili ikinci şeyin, kodunuzu birden fazla dosyada nasıl yapılandıracağını ekleyeceğim. Birçok kişi burada AMD ile gitmenizi tavsiye edebilir, ancak deneyimlerden, çok sayıda HTTP isteği nedeniyle yavaş sayfa yanıtıyla bir noktada sonuçlanacağınızı söyleyebilirim. Çıkış yolu, JavaScript modüllerinizin (dosya başına bir tane) CommonJS standardını izleyerek tek bir dosyada önceden derlenmesidir. Buradaki örneklere bir göz atın http://dsheiko.github.io/cjsc/


Tüm AMD uygulamaları ayrıca tek bir dosyada ön derleme sağlar.
I-Lin Kuo

1
Bu doğrudur, ancak elde edilen optimize edilmiş dosya, genellikle oldukça ağır olan yükleyici kütüphanesini (r.js v2.1.14 ile yeniden kontrol etmenizi gerektirir) gerektirir. Kodu derlediğimiz anda, eşzamansız olarak yüklenen bağımlılıkları çözmemize gerek yok, bu kütüphaneye ihtiyacımız yok. Sadece düşünün: Modülleri AMD'ye sarıyoruz, bu zaman uyumsuz demektir. yükledikten sonra bunları tek bir dosyada derleyin (artık ayrı yükleme yok), ancak bunları gidermek için tüm kitaplığı yükleyin (artık gereksiz olan). Bana en uygun yol gibi gelmiyor. Eşzamansız olarak yüklenmediğimizde neden AMD?
Dmitry Sheiko

almond.js, bitmiş üretim kodu için RequireJS'den daha küçük bir ağırlık yükleyici sağlar, ancak nispeten tek bir http isteği yapmamanın performans avantajı, yükleyici kodunu modüle ekleme maliyetinden çok daha ağırdır, bu yüzden daha az optimal olsa da, çok daha küçük ölçekte. Bence soru tersine çevrilmelidir - tarayıcı olmadığında neden eşzamanlılık varsayalım? Aslında, hem RequireJS hem de CommonJS'nin yerleşik bir söz uygulaması olması gerektiği görüşündeyim.
I-Lin Kuo

Her iki biçim de CommonJS Modules / 2.0 için geçerli yoldur ve aynı ölçeklenebilirliği sağlar. Bana gelince - CJS Modülleri / 1.1 ile uğraşmak (CommonJS ile demek istediğim bu) çok daha kolay, kod daha temiz görünüyor.
Dmitry Sheiko

AMD gibi avantajları bir araya geldi: * sadece JavaScript dosyaları daha yükleyebilirsiniz; * yol takma adları; CommonJS Derleyici bunları çözer - JavaScipt / JSON olmayan bağımlılıkları veri olarak yükler ve derleme yapılandırması (takma adlar dahil) ile sağlanabilir. Yapılması gereken tek dezavantaj. Ancak günümüzde herkes zaten CSS ön işlemcileri için projeyi inşa ediyor. Yani bu sadece Grunt / Gulp için ekstra bir görev ekleyerek ...
Dmitry Sheiko

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.