2011-10-02 23 views
9

Sto cercando di organizzare meglio il mio JavaScript. Il mio obiettivo è avere un'architettura modulare che possa essere suddivisa in file separati (sitename.js, sitename.utils.js ecc.).Qual è la differenza tra questi due modelli JavaScript

Mi piacerebbe sapere quali sono i vantaggi e gli svantaggi di questi due modelli e quale è più adatto per entrare in moduli che vivono in file separati.

motivo # 1 (modello modulo)

var MODULE = (function() { 

    //private methods 

    return { 
     common: { 
      init: function() { 
       console.log("common.init"); 
      } 
     }, 
     users: { 
      init: function() { 
       console.log("users.init"); 
      }, 
      show: function() { 
       console.log("users.show"); 
      } 
     } 
    } 
})(); 

modello # 2 (Singleton)

var MODULE = { 
    common: { 
    init: function() { 
     console.log("common.init"); 
    } 
    }, 

    users: { 
    init: function() { 
     console.log("users.init"); 
    }, 

    show: function() { 
     console.log("users.show"); 
    } 
    } 
}; 
+0

La prima cosa che viene in mente è che Pattern 1 consente il codice di inizializzazione che può includere dichiarazioni di variabili o funzioni che vanno immediatamente fuori dal campo di applicazione, non contaminando quindi l'ambito che lo racchiude. – Pablo

risposta

8

Personalmente, vi consiglio un'estensione di # 1, come segue:

var Module = (function(Module) { 
    // A comment 
    Module.variable1 = 3; 

    /** 
    * init() 
    */ 
    Module.init = function() { 
    console.log("init"); 
    }; 

    // ... 

    return Module; 
})(Module || {}); 

Mi piace questo motivo per un paio di motivi. Uno, la documentazione (nello specifico stile javadoc) appare più naturale quando tutte le funzioni sono dichiarazioni piuttosto che un grosso hash. Due, se i tuoi sottomoduli crescono di dimensioni, ti consente di suddividerli in più file senza alcun refactoring.

Per esempio, se Module.Users dovessero andare in un proprio file:

var Module = Module || {}; 
Module.Users = (function(Users) { 
    /** 
    * init() 
    */ 
    Users.init = function() { 
    console.log("Module.Users.init"); 
    }; 

    // ... 

    return Users; 
})(Module.Users || {}); 

Ora "module.js" e "module.users.js" possono essere file separati, e lavoreranno indipendentemente dall'ordine in cui vengono caricati. Osserva anche l'ambito locale del nome del modulo - questo è molto utile se il nome del tuo modulo è lungo, perché puoi prendere "MyApp.Users.EditScreen" e fare riferimento ad esso con una variabile come "ES" nell'ambito della definizione del tuo modulo .

+0

Il nuovo modello consente anche di aumentare il modulo in altri modi. C'è un ottimo articolo sui moduli javascript su [questo sito] (http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth) – NT3RP

+0

Questo è buono ma ottengo un errore - http: //jsfiddle.net/rjFHB/ o forse sto inizializzando Module.Users nel modo sbagliato. – howtodothis

+1

Questo è stato un mio errore: "Module.Users" non dovrebbe avere una var davanti (poiché il globale, Module, è già definito). Lo modificherò. –

2

Il primo schema consente variabili private, metodi, ecc. Tramite chiusure. Per esempio:

var MODULE = (function() { 

    var privateStuff = 'This is private'; 

    var doStuff = function(obj) { 
     console.log('Doing stuff...'); 
     console.log(privateStuff); 
    }; 

    return { 
     common: { 
      init: function() { 
       console.log("common.init"); 
       doStuff(this); 
      } 
     }, 
     users: { 
      init: function() { 
       console.log("users.init"); 
      }, 
      show: function() { 
       console.log("users.show"); 
      } 
     } 
    } 
})(); 

privateStuff e doStuff non sono proprietà dell'oggetto, e non sono disponibili per qualsiasi cosa, ma ciò che è definito all'interno della funzione che restituisce MODULE. Quindi non è possibile mostrare un esempio su come farlo con # 2.

JS non ha il concetto di membri privati, quindi non è possibile definirli tramite un normale oggetto letterale. Quindi se hai bisogno di cose private, scegli la prima opzione. Se non lo fai, però, il # 2 è più semplice.

1

Il tuo codice come scritto è praticamente lo stesso. Tuttavia, la prima forma è molto più facile da utilizzare quando si evolve il codice, poiché consente di aggiungere variabili e funzioni private. Il secondo modulo non supporta questo, e alla fine quasi sempre finisci per volere il primo modulo.

Problemi correlati