Przestrzenie nazw w Javascript
Dnia 2 maj 2010, kategoria: Javascript | Brak komentarzy »
Ostatnimi czasy przyszło mi utworzyć silnik dla GUI pewnego projektu w JS.
Nic specjalnego, jednak ze względu na rozmiary silnika (i chęć zrobienia go jak należy) postanowiłem znaleźć rozwiązanie umożliwiające korzystanie z przestrzeni nazw (namespaces), czy jak kto inny woli modułów.
Po przeczytaniu kilku poradników i przejrzeniu kilkunastu stron, trafiłem na komentarz Gravatara na tej stronie.
Przedstawiony przez niego sposób bardzo mi się spodobał. Mianowicie, jeśli chcemy korzystać z przestrzeni nazw, przed jakimkolwiek kodem z nich korzystającym (a najlepiej przed jakimkolwiek innym kodem) należy umieścić ten kod:
String.prototype.namespace = function(source) {
Object.extend(this.split('.').inject(window, function(parent, child) {
return (parent[child] = parent[child] || { });
}), source || { });
}
Dzięki temu otrzymujemy możliwość tworzenia modułów, jak np.:
'Przestrzen.Podprzestrzen.Metody'.namespace({
metoda: function(){
alert('witaj swiecie!');
},
metoda2: function(){
alert('zegnaj swiecie!')
}
});
Dzięki czemu możemy z metod zdefiniowanych w module korzystać w następujący sposób:
Przestrzen.Podprzestrzen.Metody.metoda();
Przestrzen.Podprzestrzen.Metody.metoda2();
Ale pójdźmy o krok dalej. Dlaczego nie tworzyć wewnątrz naszych modułów klas, co da nam dużo elastyczności.
Najpierw dla przykładu utwórzmy sobie prototyp klasy po której odziedziczymy (metoda z jakiej korzystam do definiowania klas wymaga zastosowania biblioteki Prototype):
var KlasaRodzic = Class.create({
metoda_klasowa: function(){
alert('jestem klasa!')
}
});
Kiedy będziemy mieli już zdefiniowanego rodzica, utworzymy przestrzeń dla naszej klasy potomka i go utworzymy, jednocześnie wskazując z jakiej klasy ma dziedziczyć:
'Przestrzen.Podprzestrzen.Klasy'.namespace({
SuperKlasa: Class.create(KlasaRodzic, {})
});
I nie pozostaje nam nic innego jak utworzyć instancję klasy i sprawdzić czy działa:
a = new Przestrzen.Podprzestrzen.Klasy.SuperKlasa();
a.metoda_klasowa();
I chyba tyle. Stosowanie przestrzeni nazw (o czym chyba mówić nie muszę) bardzo się przydaje ;)