2011-07-25 17 views
5

Próbuję znaleźć podstawowy wzorzec do tworzenia biblioteki JavaScript (klasa). Chcę zrobić to w taki sposób, aby nie zanieczyściło globalnej przestrzeni nazw masą śmieci, ale pozwoliło klasie mieć zmienne instancji i publiczne metody, które modyfikują te zmienne instancji.Wzorzec biblioteki JavaScript

Rozważmy następujący przykład zabawki. Chcę utworzyć klasę Foo. Powinien zawierać element instancji, bar, który jest liczbą. Powinien istnieć konstruktor dla Foo, który pobiera numer i inicjuje jego instancję bar z tym numerem. Powinna istnieć metoda instancji, którą można wywołać na obiekcie Foo w celu zmodyfikowania bar. Może to kod, który używa biblioteki wygląda tak:

var foo1 = new Foo(1); 
var foo2 = new Foo(2); 
console.log(foo1.bar); // should print "1" 
console.log(foo2.bar); // should print "2" 
foo2.changeBar(42); 
console.log(foo1.bar); // should print "1" 
console.log(foo2.bar); // should print "42" 

Powstały foo.js będzie używany przez aplikację internetową, a zatem zawarte poprzez znacznik skryptu w HTML.

Zrobiłem trochę wyszukiwania w Google, ale jeszcze nie znalazłem jednego, zwięzły, ogólny zarys, jak zaprojektować klasę JavaScript (używane jako biblioteka).

Odpowiedz

9
(function() { 
    Foo = function (num) { 
     this.changeBar(num); 
    }; 

    var privateMethod = function (x) { 
     if (this.bar === 999) { 
      this.bar = x; 
     } 
    }; 

    Foo.prototype.changeBar = function (num) { 
     this.bar = num; 
     privateMethod.call(this, 1); 
    }; 

}()); 

To jest najprostszy sposób na zrobienie tego. Nie musisz uwzględniać definicji w zamknięciu, a bardziej w stylu.

+0

+1 również. Zamknięcie ma pewne subtelne zalety. Możesz zdefiniować "prywatne" funkcje wewnątrz zamknięcia, które może wywoływać Twój prototyp i funkcje członkowskie. – selbie

+0

@ Czy zdefiniowałabyś taką prywatną funkcję i jak by ją nazwać? –

+1

Edytowałem powyższą odpowiedź Evan, aby uwzględnić prywatną metodę. Funkcja "privateMethod" nie może być wywołana z wyjątkiem innych funkcji w obrębie zamknięcia. – selbie

7

Opierając się na odpowiedzi Evana, aby pokazać trochę więcej możliwości. Większość normalnych przypadków wykorzystuje jednak tylko niektóre z nich.

(function() { 
    //When we create variables inside a function they can only be seen by other 
    // inner functions. Wraping all our code here makes sure noone gets to see 
    // the private stuff. 

    //The first opening parenthesis is required for Javascript to parse it 
    //correctly though 


    //this is the constructor function 
    //Note how we set a global variable (Foo) to make it available outside. 
    Foo = function(num, another_num) { 

     this.changeBar(num); 

     //sometimes you will want to make a method that modifies a variable 
     //that can't be acessed via this.xxx. You can use a closure here for that 
     //(there are some performance considerations though) 

     this.baz = function(){ 
      console.log(another_num); 
     } 

     //Setting methods "by hand" like this is also useful if you want to 
     //do multiple inheritance, since you can just set all methods of the 
     //second class by hand here if you want. 
    } 

    //Things on Foo.prototype will be available for all Foo objects, 
    // via prototypal inheritance magic. 
    Foo.prototype.changeBar = function(num) { 
     this.bar = num; 
    } 

    var a_secret_variable = 42; 

    function my_private_function(){ 
     console.log(a_secret_variable); 
    } 

    //All private variables can be normaly used (by functions that can see them). 
    Foo.prototype.use_magic = function(){ 
     my_private_function(); 
    } 

}()); 
//The "fake" function is imediatelly called, 
//so in the end all it does is create a inner scope. 
Powiązane problemy