Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> JS.Class biblioteka ułatwiająca tworzenie i rozszerzanie obiektów w JSie, http://code.google.com/p/jsclassextend/
deirathe
post
Post #1





Grupa: Zarejestrowani
Postów: 426
Pomógł: 32
Dołączył: 24.05.2007

Ostrzeżenie: (0%)
-----


http://code.google.com/p/jsclassextend/

Mała biblioteka do tworzenia i rozszerzania obiektów w JSie. Prosta klasa:


  1. var Sample = JS.Class({
  2. test : function () {
  3. }
  4. });



rozszerzanie:
  1. var ExtendedSample = Sample.extend({
  2. test2 : function () {
  3. }
  4. });


instancja:

  1. var obj = new ExtendedSample();


więcej przykładów na googlecodzie, zapraszam do komentów (IMG:style_emoticons/default/smile.gif)

Ten post edytował deirathe 11.01.2011, 22:34:05
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
zegarek84
post
Post #2





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


JavaScript jest specyficzny - aby zrozumieć o co mi chodziło przeczytaj także komentarze w przykładowych krótkich kodach

zależy co rozumiesz tutaj przez extend - jeśli to co np. w PHP extends rozszerzanie klas to obiekt przekazywany w metodzie extend nie powinien nadpisywać zmiennych - nadpisywanie powinno być w drugą stronę... nie działa także instanceof...

chyba, że chciałeś w drugą stronę, że dla przykładu cTest.extend(cTest2) - że cTest2 zostanie rozszerzone o cTest - jednak instanceof także nie działa gdy sobie zrobimy obiekt oTest2 = new cTest2; alert(oTest2 instanceof cTest);

dla przykładu tutaj np. zamiast zapisać:
[JAVASCRIPT] pobierz, plaintext
  1. var TestClass = JS.Class({
  2. a: 9,
  3. methodA : function (param) {
  4. //method body
  5. $('#hello').append(param);
  6. }
  7. });
  8. var oTest = new cTest;
  9. var cExtendedTestClass = TestClass.extend(oTest);
[JAVASCRIPT] pobierz, plaintext

można zapisać:
[JAVASCRIPT] pobierz, plaintext
  1. var cExtendedTestClass = JS.Class({
  2. a: 9,
  3. methodA : function (param) {
  4. //method body
  5. $('#hello').append(param);
  6. }
  7. }).extend(oTest);
  8. // lub ...extend(cTest)
  9. // gdzie oTest - obiekt, cTest - klasa - czyli także obiekt, tyle, że to konstruktor i funkcja...
[JAVASCRIPT] pobierz, plaintext


dokładniej o co mi chodzi zawarłem w przykładach
[JAVASCRIPT] pobierz, plaintext
  1. var cTest = function(){
  2. };
  3. cTest.prototype = {
  4. a: 2,
  5. b: 3
  6. };
  7.  
  8. //sample js class
  9. var TestClass = JS.Class({
  10. a: 9,
  11. methodA : function (param) {
  12. //method body
  13. $('#hello').append(param);
  14. }
  15. });
  16. var oTest = new cTest;
  17. var cExtendedTestClass = TestClass.extend(oTest);
  18.  
  19. var oExtendedTestClass = new cExtendedTestClass();
  20.  
  21. // return false, 2, 3, false;
  22. // powinno być: true, 9, 3 ?jaki może ma być inna logika?
  23. alert([oExtendedTestClass instanceof cTest, oExtendedTestClass.a, oExtendedTestClass.b, oTest instanceof cExtendedTestClass]);
  24.  
  25. var cNewClass = function(){};
  26. // extend cTest
  27. cNewClass.prototype = new cTest;
  28. // other methods
  29. cNewClass.prototype.a = 9;
  30. cNewClass.prototype.fCos = function(){};
  31. cNewClass.prototype.fOther = function(){};
  32.  
  33. var oNewClass = new cNewClass;
  34.  
  35. // return true, 9, 3;
  36. // powinno być: true, 9, 3
  37. alert([oNewClass instanceof cTest, oNewClass.a, oNewClass.b]);
[JAVASCRIPT] pobierz, plaintext


[edit]

jeszcze zapomniałem - przyczepiłbym się jeszcze do zmiennych "statycznych" - wiem, że wielu używa tej nazwy do tego typu konstrukcji, ale dla mnie używając tego określenia to co się robi na zmiennych powinno się dziać np. tak jak w PHP, że nie ważne z którego obiektu próbujesz się odwołać - czy to z wnętrza czy z zewnątrz [pomijam protected i public] to we wszystkich obiektach także utworzonych z dziedziczonych klas ta zmienna powinna mieć tą samą wartość... jak dla mnie skoro obiekty są przekazywane przez referencję to do prototypu dodałbym taki obiekt o stałej nazwie i co konstruktora funkcji o tej samej nazwie np. statyczne - czyli w efekcie cTest.statyczne['jakaś zmienna'] - a wewnątrz po stworzeniu obiektu np. this.statyczne['jakaś zmienna']...

ale to tak ogólnikowo piszę tylko ;] - jak to robiłeś, czy w prototypie konstruktora czy inaczej to kodu nie analizowałem...
nie sprawdzałem czy do extend można dać funkcję - no wiadomo, że można gdyż funkcja jest także obiektem, ale miałem na myśli, czy sprawdzasz, że jest to instanceof Function - gdyż jeśli tak to pasuje potraktować ją jako konstruktor lub jeśli rozszerzasz w drugą stronę to zamiast bezpośrednio iterować po funkcji to powinno się po jej prototypie...

Ten post edytował zegarek84 12.01.2011, 00:33:45
Go to the top of the page
+Quote Post
deirathe
post
Post #3





Grupa: Zarejestrowani
Postów: 426
Pomógł: 32
Dołączył: 24.05.2007

Ostrzeżenie: (0%)
-----


Dzięki wielkie za tak wyczerpującą opinię. Słowo static to bardziej definicja constansów niż staticów, dlatego cieszę się że zwróciłeś mi na to uwagę. Co do extenda:
http://jsfiddle.net/lunereaper/BbRdB/18/
tu jest przykład jak to działa i jak dziala instanceof, mi zwracał true.

[JAVASCRIPT] pobierz, plaintext
  1. var cTest = function(){
  2. };
  3. cTest.prototype = {
  4. a: 2,
  5. b: 3
  6. };
  7.  
  8. //sample js class
  9. var TestClass = JS.Class({
  10. a: 9,
  11. methodA : function (param) {
  12. //method body
  13. }
  14. });
  15. var oTest = new cTest;
  16.  
  17. var cExtendedTestClass = TestClass.extend(oTest);
  18.  
  19. var oExtendedTestClass = new cExtendedTestClass();
  20. //true, true
  21. console.log([oExtendedTestClass instanceof cExtendedTestClass, oExtendedTestClass instanceof TestClass]);
[JAVASCRIPT] pobierz, plaintext


Co do Twojego przykładu- nie pomyślałem o takim użyciu tej biblioteki, ale taką funkcjonalność na pewno wprowadzę i za to spostrzeżenie jestem niezmiernie wdzięczny. Na razie jednak można rozszerzać klasy w sposób opisany w mini dokumentacji, czyli za pomocą JSON'a. Instanceof nie działa kiedy sprawdzasz go na swojej klasie, ponieważ do prototypu obiektu, który powstanie za pomocą zdefiniowanej klasy nie jest przypisywany prototyp wrzuconego obiektu a prototyp obiektu który rozszerzamy.

No i tak jak wspomniałeś JS jest nietypowy, dlatego też wszystkie atrybuty w klasie będące obiektami powinny być definiowane w "construct", aby uniknąć niemiłych niespodzianek.

Ten post edytował deirathe 12.01.2011, 01:37:25
Go to the top of the page
+Quote Post
zegarek84
post
Post #4





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


rzeczywiście przy takim stosowaniu instanceof działa ;]...

tylko jak wspomniałem logika wydawała się inna ze względu konstrukcji:
[JAVASCRIPT] pobierz, plaintext
  1. JS.Class({
  2. construct : function () {
  3. this.holder = $('#hello');
  4. },
  5. methodA : function ()
  6. {
  7. this.holder.html('method a');
  8. }
  9. }).extend({});
[JAVASCRIPT] pobierz, plaintext

co w wolnym tłumaczeniu dla mnie znaczyło, iż dziedziczę z klasy podanej w parametrze extend - a jeśli nie podana klasa (funkcja) tylko gotowy obiekt to w tym moim tłumaczeniu metody i zmienne znajdujące się w obiekcie przekazanym do Class() powinny mieć pierwszeństwo i nie powinny być nadpisywane przez zmienne z extend (przynajmniej jak to jest np. w PHP) - podczas gdy do obecnego działania bardziej pasuje nazwa w stylu "dodaj/nadpisz metody i zwróć klasę nie dotykając tej którą tworzę/lub mam" - jakby ciutkę inna logika

swoją drogą jeśli chcieć tworzyć nową klasę rozszerzając inną to można by metodę JS.Class zrobić na 2 parametry - gdzie drugi byłby opcjonalny...
JS.Class(oKonstrukcjaKlasy, oObiekt/KlasaPoKtórymDziedziczymy)....

[JAVASCRIPT] pobierz, plaintext
  1. var cKlasa = JS.Class({
  2. construct : function () {
  3. this.holder = $('#hello');
  4. },
  5. methodA : function ()
  6. {
  7. this.holder.html('method a');
  8. }
  9. },
  10. oJakiśObiekt/KonstruktorKlasy);
  11. // lub z jednym parametrem
  12. var cKlasa2 = JS.Class({
  13. construct : function () {
  14. this.holder = $('#hello');
  15. }
  16. });
  17. // w sumie to i jeśli nikt nie poda pierwszego parametru można by zwrócić po prostu anonimową funkcję czyli pustą klasę
  18. var cKlasa2 = JS.Class();
[JAVASCRIPT] pobierz, plaintext


ps.
jeszcze teraz przyszło mi do głowy coś takiego, że można by jeszcze dorobić np. obsługe abstrakcyjnych metod... a można by to zrobić np. w ten deseń, że np. definiujesz zmienną window.abstract = {} (lub tablica [] lub anonimowa funkcja - nie ważne)... dalej jeszcze tą zmienną sobie zbuforujesz gdzie trzeba - ale mając taką zmienną w window można pisać np. {g: abstract} - a potem w konstruktorze lub na extend strawdzasz czy zmienna !== abstract (jeśli będzie false to trzeba wyrzucić jakiś wyjątek informujący o braku implementacji metody o nazwie...)... z kolei klasy abstrakcyjne mógłbyś utworzyć w taki sposób, że w konstruktor daje się funkcję itterująca po własnych metodach i sprawdzającą czy czasem zmienna nie równa się abstract i wyrzucić wyjątek jeśli komuś przyjdzie do głowy tworzenie obiektu z takiej klasy

oczywiście nazwa abstract jest raczej zarezerwowana [czy jak się to zwie...]

pozdro (IMG:style_emoticons/default/winksmiley.jpg)

Ten post edytował zegarek84 12.01.2011, 01:59:40
Go to the top of the page
+Quote Post
deirathe
post
Post #5





Grupa: Zarejestrowani
Postów: 426
Pomógł: 32
Dołączył: 24.05.2007

Ostrzeżenie: (0%)
-----


Nie wiem czy patrzyłeś może w kod który tam leży na googl'u. Twój pomysł mi się mega podoba, ale nie mam koncepcji na chwilę obecną jak tego dokonać (IMG:style_emoticons/default/biggrin.gif) tak żeby instanceof działał jak należy (IMG:style_emoticons/default/smile.gif)

[JAVASCRIPT] pobierz, plaintext
  1. var Test = JS.Class({
  2. a : function() {console.log('3');}
  3. });
  4.  
  5. var eTest = Test.extend({
  6. a : function() {console.log('5');}
  7. });
  8.  
  9. var v = new eTest();
  10. v.a();
[JAVASCRIPT] pobierz, plaintext


To to samo co w php
  1. class Test
  2. {
  3. public function a () { echo "3";}
  4. }
  5. class eTest extends Test
  6. {
  7. public function a () { echo "5";}
  8. }
  9.  
  10. $v = new eTest();
  11.  
  12. $v->a();


Cytat(zegarek84 @ 12.01.2011, 01:43:41 ) *
ps.
jeszcze teraz przyszło mi do głowy coś takiego, że można by jeszcze dorobić np. obsługe abstrakcyjnych metod... a można by to zrobić np. w ten deseń, że np. definiujesz zmienną window.abstract = {} (lub tablica [] lub anonimowa funkcja - nie ważne)... dalej jeszcze tą zmienną sobie zbuforujesz gdzie trzeba - ale mając taką zmienną w window można pisać np. {g: abstract} - a potem w konstruktorze lub na extend strawdzasz czy zmienna !== abstract (jeśli będzie false to trzeba wyrzucić jakiś wyjątek informujący o braku implementacji metody o nazwie...)... z kolei klasy abstrakcyjne mógłbyś utworzyć w taki sposób, że w konstruktor daje się funkcję itterująca po własnych metodach i sprawdzającą czy czasem zmienna nie równa się abstract i wyrzucić wyjątek jeśli komuś przyjdzie do głowy tworzenie obiektu z takiej klasy

oczywiście nazwa abstract jest raczej zarezerwowana [czy jak się to zwie...]

pozdro (IMG:style_emoticons/default/winksmiley.jpg)


Abstract będzie dużo łatwiejsze, można to zrobić tak jak ze static'iem:

[JAVASCRIPT] pobierz, plaintext
  1. var Test = JS.Class({
  2. abstract : {
  3. properties : ['propA','propB'],
  4. methods: ['methodA','methodB']
  5. }
  6. });
[JAVASCRIPT] pobierz, plaintext



Ten post edytował deirathe 12.01.2011, 01:59:38
Go to the top of the page
+Quote Post
zegarek84
post
Post #6





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


do samych źródeł nie zaglądałem - trochu nie mam czasu - tylko na przykłady...

Cytat(deirathe @ 12.01.2011, 02:04:38 ) *
...To to samo co w php...

właśnie dlatego się pytałem w którą stronę jest tutaj dziedziczenie gdyż z samej konstrukcji js nie wiedziałem (IMG:style_emoticons/default/winksmiley.jpg) - fakt faktem sam mogłem sprawdzić pisząc coś na wzór:
[JAVASCRIPT] pobierz, plaintext
  1. var TestClass = JS.Class({
  2. construct : function () {
  3. this.iA = 2;
  4. }
  5. });
  6.  
  7. var ExtendedTestClass = TestClass.extend({
  8. construct : function () {
  9. this.iA = 3;
  10. },
  11. fAlert: function(){alert(this.iA);}
  12. });
  13.  
  14. var oTest = new ExtendedTestClass;
  15. oTest.fAlert();
[JAVASCRIPT] pobierz, plaintext

tyle, że jak już wcześniej wspominałem skoro w extend jest szkielet klasy to tutaj ta nazwa jakoś mi nie pasuje...

pozdro... widzę, iż wiesz co gdzie i to dosyć dobrze napisałeś choć jeszcze można to dopracować by nie było niejasności (IMG:style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
bendi
post
Post #7





Grupa: Zarejestrowani
Postów: 401
Pomógł: 5
Dołączył: 14.09.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


To się przyczepie - zamiast wołania apply, możesz zastosować call i nie przekazywać sztucznej tablicy. Co do własności z podkreśleniem to mam mieszane uczucia, ale rozumiem, że to konwencja dostępu prywatnego.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 17.09.2025 - 20:13