2012-05-21 14 views
9

Cuando intento crear diferentes instancias de este módulo, no funciona.¿Por qué el patrón de módulo crea un singleton?

Parece ser un singleton. Solo puedo tener una instancia a la vez.

¿Qué mecanismo limita la función del constructor publik() para tener solo en la instancia?

http://jsfiddle.net/AVxZR/

var Module = (function() 
{ 
    var publik = function () 
    { 
    }; 
    publik.prototype.test; 
    publik.prototype.get = function() 
    { 
     document.getElementById('a'+test).innerHTML = test; 
    }; 
    publik.prototype.set = function(value) 
    { 
     test = value; 
    }; 
    return publik; 
})(); 

var object1 = new Module(); 
var object2 = new Module(); 

object1.set('1'); 
object2.set('2'); 


object1.get(); 
object2.get(); 

Respuesta

5

La respuesta corta: cierre.

La respuesta larga (si lo tengo, por favor comentar para que pueda corregir):

  1. Su var módulo es un ejecutadas inmediatamente cuando se carga el script. (indicado por el paréntesis alrededor de la función.)()

  2. En ese módulo, su publik var está declarada y queda en el cierre incluso cuando la función finaliza.

  3. Con las llamadas subsiguientes, sigue teniendo acceso a ese módulo que se ejecutó automáticamente. Y siempre obtiene ese mismo espacio de cierre y alcance de función y el mismo objeto, en resumen, para que su variable publik sea siempre la misma.

+0

Entonces, cada vez que llamo nuevo, ¿no es realmente un nuevo objeto de función, es el mismo? –

+1

Sí.Para ser más correctos, cuando encierra una función en el patrón (función() {}()), se ejecuta automáticamente en el tiempo de carga y el resultado se coloca en su lugar. Entonces su script al final parece (internamente) var Module = YourObjectWithGetAndSetMethods; Y cuando haces un var x = Module(); Está llamando a un objeto que ya está instanciado y, por lo tanto, con una variable publik instanciada. – Zlatko

+0

me parece un patrón falso. "Rompe" el significado de la palabra clave "nuevo". ¿Estás de acuerdo? Si es así, ¿por qué la gente usa esto? Obviamente no lo inventé. –

4

intente volver a escribir la clase del módulo de manera que se puede usar para crear diferentes instancias. Es posible que desee alterar la propiedad "prueba" para que sea una propiedad estática, ya que la cambié por usted.

var Module = function(){} 

    Module.prototype.test; 
    Module.prototype.get = function() 
    { 
     document.getElementById('a'+this.test).innerHTML = this.test; 
    }; 
    Module.prototype.set = function(value) 
    { 
     this.test = value; 
    } 
+0

Lo he usado antes pero no me gusta el estilo b.c. no hay corchetes abarcativos –

10

El patrón del módulo no está destinado a ser utilizado de la manera que usted ha descrito. Se usa para crear un módulo y ocultar el estado del código externo, es decir, expone una interfaz pública con la que se puede comunicar el código externo pero mantiene el resto oculto.

Esto evita que otros códigos se basen en variables o funciones que está utilizando internamente, ya que se romperían cuando cambie el nombre.

Además, se supone que un módulo es singleton; tener múltiples módulos idénticos es como tener dos clases idénticas en tu código ... no tiene sentido.

Así es como debe verse un patrón de módulo.

var Module = (function($) { 
    // the $ symbol is an imported alias 

    // private variable 
    var id = 0; 

    // private function 
    function increaseId() 
    { 
     return ++id; 
    } 

    // return public interface 
    return { 
     nextId: function() { 
      // we have access to the private function here 
      // as well as the private variable (btw) 
      return increaseId(); 
     } 
    } 
}(jQuery)); // we import jQuery as a global symbol 

Module.nextId(); // 1 
Module.nextId(); // 2 
Module.id; // undefined 
Module.increaseId(); // error 

a ver cómo sólo se expone .nextId(), pero ninguna de las otras variables/funciones privadas.

1

Su código no crea un singleton. Solo actúa como un singleton ya que su variable test es una variable global.

Para solucionar este cambio test-this.test así la variable está unida a cada instancia.

Cuestiones relacionadas