2010-10-10 14 views
6

Obecnie znam dwa sposoby konstruowania singletonów w JavaScript. Po pierwsze:Jak utworzyć singleton JavaScript z konstruktorem bez użycia zwrotu?

var singleton = { 
publicVariable: "I'm public", 
publicMethod: function() {} 
}; 

Jest doskonały z wyjątkiem tego, że nie ma konstruktora, w którym mógłbym uruchomić kod inicjalizacyjny.

drugie:

(function() { 

var privateVariable = "I'm private"; 
var privateFunction = function() {} 

return { 
publicVariable: "I'm public", 
publicMethod: function() {} 
} 

})(); 

Pierwsza wersja nie posiada właściwości prywatnych ani nie ma konstruktora, ale jest szybsze i prostsze. Druga wersja jest bardziej skomplikowana, brzydka, ale ma konstruktora i właściwości prywatne.

Nie potrzebuję prywatnych nieruchomości, po prostu chcę mieć konstruktora. Czy jest coś, czego mi brakuje, czy też oba podejścia są powyżej jedynych, które mam?

+1

Drugie podejście nie jest "brzydkie"; to naturalna część języka. Możliwość tworzenia funkcji za pomocą funkcji jest jedną z najpotężniejszych funkcji Javascript. – Pointy

Odpowiedz

7
function Singleton() { 
    if (Singleton.instance) 
    return Singleton.instance; 
    Singleton.instance = this; 
    this.prop1 = 5; 
    this.method = function() {}; 
}​ 
+0

Myślę, że to rozwiązanie nie jest jasne, ponieważ użycie tego konstruktora jest następna: 'new Singleton()'. Oznacza to, że programista spodziewa się uzyskać nową instancję za każdym razem, gdy napisze ten kod. To znaczy. 'new Singleton() == new Singleton()' zwraca 'true', ale musi zwracać' false'. – pto3

1
var singleton = new function() { // <<----Notice the new here 
    //constructorcode.... 

    this.publicproperty ="blabla"; 
} 

To jest w zasadzie taka sama jak tworzenie funkcji, a następnie natychmiast assiging nowy instace go do zmiennej Singleton. Podobnie jak var singleton = new SingletonObject();

Gorąco radzę unikać używania singletonów w ten sposób w javscript choć ze względu na kolejność wykonywania opiera się na tym, gdzie w pliku umieszczasz obiekt, a nie na własnej logice.

1

Co z tym?

var Singleton = (function() { 
    var instance; 

    // this is actual constructor with params 
    return function(cfg) { 
     if (typeof instance == 'undefined') { 
      instance = this; 
      this.cfg = cfg; 
     } 
     return instance; 
    }; 
})(); 

var a = new Singleton('a'); 
var b = new Singleton('b'); 

//a === b; <-- true 
//a.cfg <-- 'a' 
//b.cfg <-- 'a' 
2

Oto moje rozwiązanie z zamknięciami:

function Singleton() { 

    Singleton.getInstance = (function(_this) { 
     return function() { return _this; }; 
    })(this); 
} 

Test:

var foo = new Singleton(); 
var bar = Singleton.getInstance(); 
foo === bar; // true 
2

Jeśli tylko szukasz miejsca do Inicjalizację Singleton, jak ten temat?

var singleton = { 
    'pubvar': null, 
    'init': function() { 
     this.pubvar = 'I am public!'; 
     return this; 
    } 
}.init(); 

console.assert(singleton.pubvar === 'I am public!'); 

Prosty i elegancki.

Powiązane problemy