2011-10-02 10 views
9

Estoy intentando organizar mi JavaScript mejor. Mi objetivo es tener una arquitectura modular que pueda dividir en archivos separados (sitename.js, sitename.utils.js, etc.).Cuál es la diferencia entre estos dos patrones de JavaScript

Me gustaría saber cuáles son las ventajas y desventajas de estos dos patrones y cuál es más adecuado para dividir en módulos que viven en archivos separados.

patrón # 1 (patrón módulo)

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"); 
      } 
     } 
    } 
})(); 

patrón # 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

Lo primero que se le viene a la mente es que el Patrón 1 permite el código de inicialización que puede incluir declaraciones de funciones o variables que salgan inmediatamente del alcance, por lo que no contaminan el alcance envolvente. – Pablo

Respuesta

8

Personalmente, recomiendo una extensión de # 1, como sigue:

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

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

    // ... 

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

Me gusta este patrón por un par de razones. Una, la documentación (específicamente el estilo javadoc) parece más natural cuando todas tus funciones son declaraciones en lugar de un gran hash. Dos, si tus submódulos crecen en tamaño, te permite dividirlos en varios archivos sin ninguna refactorización.

Por ejemplo, si Module.Users debían ir en su propio archivo:

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

    // ... 

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

Ahora "module.js" y "module.users.js" puede haber archivos separados, y que va a trabajar independientemente del orden en que estén cargados. También tenga en cuenta el alcance local del nombre del módulo; esto es muy útil si su nombre de módulo es largo, porque puede tomar "MyApp.Users.EditScreen" y referirse a él con una variable como "ES" dentro del alcance de la definición de su módulo .

+0

El nuevo patrón también permite aumentar el módulo de otras maneras. Hay un artículo realmente bueno sobre módulos de JavaScript en [este sitio] (http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth) – NT3RP

+0

Esto es bueno, pero me sale un error - http: //jsfiddle.net/rjFHB/ o quizás estoy inicializando Module.Users de la manera incorrecta. – howtodothis

+1

Ese fue mi error: "Module.Users" no debería tener una var en frente (ya que el módulo global ya está definido). Voy a editar eso. –

2

El primer patrón permite variables privadas, métodos, etc. a través de cierres. Por ejemplo:

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 y doStuff no son propiedades del objeto, y no están disponibles para cualquier cosa menos lo que está definido dentro de la función que devuelve MODULE. Entonces, mostrar un ejemplo de cómo hacer esto con el # 2 no es posible.

JS no tiene el concepto de miembros privados, por lo que no puede definirlos a través de un literal de objeto regular. Entonces, si necesitas cosas privadas, ve por la primera opción. Si no lo hace, sin embargo, el # 2 es más simple.

1

Su código tal como está escrito es prácticamente el mismo. Sin embargo, es más fácil trabajar con la primera forma a medida que evoluciona el código, porque le permite agregar variables y funciones privadas. La segunda forma no es compatible con esto, y casi siempre terminas queriendo la primera forma eventualmente.

Cuestiones relacionadas