O :) Nie wiedziałem, że constructor można zmieniać.
Z ciekawości - który sposób tworzenia konstruktorów preferujesz? Pamiętam, że jeszcze o problemie z prototypem rozmawialiśmy, ale pokazałeś mi dziedziczenie funkcyjne. Tak więc wydaje się, że obydwie metody są równie funkcjonalne. Czy może jednak w praktyce wychodzi, że metoda ze zwracaniem obiektu wymaga tyle nadmiarowego kodu by zachowywać się "ładnie", że jest niewygodna?
Szymon
02 marca 2010 o 20:41:10
ferrante, mi się takie konstrukcje zawsze trochę nieeleganckie wydawały ze względu na to że mam fn "na zewnątrz" i "wewnątrz", tzn jak bym np. chciał zmienić "nazwę" konstruktora "fn" na "foo" to muszę zaglądać do wnętrza kodu i tam też zmieniać, preferuję takie cuś (nie twierdzę że tak się powinno robić, tylko że mi się bardziej podoba)
js> var Cons4 = (function (f) { f = function () { var obj = { sth: 'sth' }; obj.constructor = f; return obj; }; return f; })();
js> var x = Cons4();
js> var y = Cons4();
js> x.constructor === y.constructor
true
js> x.constructor === Cons4
true
js> x.constructor
function () {
var obj = {sth:"sth"};
obj.constructor = f;
return obj;
}
Szczerze... to już dla mnie przerost formy nad treścią :D Tzn tak samo inne dziwne rozwiązania, gdzie trzeba dopisać coś żeby zaczęły działać w spodziewany sposób. Chyba to jest główny powód dla którego lubię rozwiązanie pierwsze. Po prostu tak jest i działa.
Szymon
02 marca 2010 o 20:58:44
w tym konkretnym przypadku (który do niczego prócz demonstracji nie służy) owszem, tyle że wersja przyjemniejsza dla oka nie jest odporna na pewne sytuacje, a do innych w ogóle się nie nadaje ( np. kiedy masz listę konstruktorów a nie każdy przypisany do osobnej zmiennej).
Szymon
02 marca 2010 o 20:59:33
tzn. pisząc o wersji przyjemniejszej miałem na myśli tę ferrente z "fn".
Szymon
02 marca 2010 o 21:08:59
btw, co do przerostu formy nad treścią -- w przypadku js sprawa z tworzeniem obiektów nie jest oczywista (o czym zresztą traktuje Twój artykuł), poczytaj Crockforda: http://javascript.crockford.com/prototypal.html. Zgłosił to ale (http://www.crockford.com/javascript/recommend.html) nie obiło mi się o uszy że przeszło.
Właśnie to rozwiązanie zaproponowane przez Ferrante też uważam za niemiłe dla oka :) Tzn. lekko niemiłe, ale niemiłe. Zawsze to jest ta jedna linia, którą trzeba dopisać i o której można zapomnieć. Do tego od razu przechodzimy do dziedziczenia funkcyjnego, które co prawda jest ładne, ale też nie jest "czyste" i żeby __proto__ zaczęło działać (tylko po co komu ono) trzeba kilka linii zawsze dopisać.
Niby .constructor i .__proto__ przydatne raczej nie są. Jednak o ile z jakiegoś powodu nie musimy/wygodniej nam skorzystać z rozwiązania z object literalsami, to po co sobie kombinować życie? Tylko, że ja mam za małe doświadczenie by stwierdzić, jak to w praniu wychodzi.
A za artykuły dzięki - przeczytam w wolnej chwili.
Szymon
02 marca 2010 o 21:39:05
ja też nie wiem jak to w praniu wychodzi ;)
btw, wbrew temu co kiedyś było napisane na wikipedii język na którym JS jest troszkę (prototypowanie) wzorowany wciąż żyje i można by się pobawić celem poszerzenia horyzontów ;)
http://selflanguage.org/ ;)
Wracając jeszcze do tego problemu, która z metod jest lepsza, to tak myślę, że moc JSa drzemie właśnie w tym, że... ten problem istnieje :> Bo to oznacza, że język jest elastyczny i w zależności od kontekstu można wybrać wygodniejsze rozwiązanie. A nie jak Java - jedna klasa, druga klasa, interfejs, interfejs, jakieś abstrakcyjne bzdety i znowu klasy. W sumie z podobnego powodu python mi się spodobał - też jest elastyczny. Tylko ciągle czasu brakuje, żeby się go nauczyć porządnie :)
Szymon, no ok, Twoje jest bardzo eleganckie, ale ja tylko podawalem przyklad, ze da sie przypisac do objektu .constructor ;-) No less, no more.
Inna sprawa, abstrahując od tej dyskusji to, że dawno już nie musiałem używać instanceof i bawić się .constructorami. Anonimowe obiekty w wiekszosci przypadkow wystarczaja.
Generalnie dla mnie najlepszy jest sposob podany przez Szymona, a ze tego typu dziwolagi sie uzywa.. spójrzcie sobie na generatory klas w mootools na przyklad ;-)
Z drugiej strony zacząłem dzisiaj pisać małą biblioteczkę na własny użytek i po 100 liniach kodu dochodzę od wniosku że dziwne konstrukcje tam po tworzyłem (niekoniecznie dobre, pewnie ;). Może to ten język tak wymaga ;)?
Ale masz brzydkie fonty w tym Firebugu.
Te obrazki wstawione tutaj na bloga się brzydko przeskalowaly, bo tylko w poziomie.
Dzieki. Z ciekawoscia przeczytalem zarowno pierwsza jak i druga czesc
Piotrek, jak zwykle bardzo dobry artykul. Co do ostatniego akapitu z .constructor, mozesz zrobic tak:
var fn = function() {
var obj = {};
obj.constructor = fn;
obj.cos = 1;
return obj;
};
var o = new fn;
o.constructor.toString();
Pozdrawiam
O :) Nie wiedziałem, że constructor można zmieniać.
Z ciekawości - który sposób tworzenia konstruktorów preferujesz? Pamiętam, że jeszcze o problemie z prototypem rozmawialiśmy, ale pokazałeś mi dziedziczenie funkcyjne. Tak więc wydaje się, że obydwie metody są równie funkcjonalne. Czy może jednak w praktyce wychodzi, że metoda ze zwracaniem obiektu wymaga tyle nadmiarowego kodu by zachowywać się "ładnie", że jest niewygodna?
ferrante, mi się takie konstrukcje zawsze trochę nieeleganckie wydawały ze względu na to że mam fn "na zewnątrz" i "wewnątrz", tzn jak bym np. chciał zmienić "nazwę" konstruktora "fn" na "foo" to muszę zaglądać do wnętrza kodu i tam też zmieniać, preferuję takie cuś (nie twierdzę że tak się powinno robić, tylko że mi się bardziej podoba)
js> var Cons4 = (function (f) { f = function () { var obj = { sth: 'sth' }; obj.constructor = f; return obj; }; return f; })();
js> var x = Cons4();
js> var y = Cons4();
js> x.constructor === y.constructor
true
js> x.constructor === Cons4
true
js> x.constructor
function () {
var obj = {sth:"sth"};
obj.constructor = f;
return obj;
}
Szczerze... to już dla mnie przerost formy nad treścią :D Tzn tak samo inne dziwne rozwiązania, gdzie trzeba dopisać coś żeby zaczęły działać w spodziewany sposób. Chyba to jest główny powód dla którego lubię rozwiązanie pierwsze. Po prostu tak jest i działa.
w tym konkretnym przypadku (który do niczego prócz demonstracji nie służy) owszem, tyle że wersja przyjemniejsza dla oka nie jest odporna na pewne sytuacje, a do innych w ogóle się nie nadaje ( np. kiedy masz listę konstruktorów a nie każdy przypisany do osobnej zmiennej).
tzn. pisząc o wersji przyjemniejszej miałem na myśli tę ferrente z "fn".
btw, co do przerostu formy nad treścią -- w przypadku js sprawa z tworzeniem obiektów nie jest oczywista (o czym zresztą traktuje Twój artykuł), poczytaj Crockforda: http://javascript.crockford.com/prototypal.html. Zgłosił to ale (http://www.crockford.com/javascript/recommend.html) nie obiło mi się o uszy że przeszło.
Właśnie to rozwiązanie zaproponowane przez Ferrante też uważam za niemiłe dla oka :) Tzn. lekko niemiłe, ale niemiłe. Zawsze to jest ta jedna linia, którą trzeba dopisać i o której można zapomnieć. Do tego od razu przechodzimy do dziedziczenia funkcyjnego, które co prawda jest ładne, ale też nie jest "czyste" i żeby __proto__ zaczęło działać (tylko po co komu ono) trzeba kilka linii zawsze dopisać.
Niby .constructor i .__proto__ przydatne raczej nie są. Jednak o ile z jakiegoś powodu nie musimy/wygodniej nam skorzystać z rozwiązania z object literalsami, to po co sobie kombinować życie? Tylko, że ja mam za małe doświadczenie by stwierdzić, jak to w praniu wychodzi.
A za artykuły dzięki - przeczytam w wolnej chwili.
ja też nie wiem jak to w praniu wychodzi ;)
btw, wbrew temu co kiedyś było napisane na wikipedii język na którym JS jest troszkę (prototypowanie) wzorowany wciąż żyje i można by się pobawić celem poszerzenia horyzontów ;)
http://selflanguage.org/ ;)
Wracając jeszcze do tego problemu, która z metod jest lepsza, to tak myślę, że moc JSa drzemie właśnie w tym, że... ten problem istnieje :> Bo to oznacza, że język jest elastyczny i w zależności od kontekstu można wybrać wygodniejsze rozwiązanie. A nie jak Java - jedna klasa, druga klasa, interfejs, interfejs, jakieś abstrakcyjne bzdety i znowu klasy. W sumie z podobnego powodu python mi się spodobał - też jest elastyczny. Tylko ciągle czasu brakuje, żeby się go nauczyć porządnie :)
Szymon, no ok, Twoje jest bardzo eleganckie, ale ja tylko podawalem przyklad, ze da sie przypisac do objektu .constructor ;-) No less, no more.
Inna sprawa, abstrahując od tej dyskusji to, że dawno już nie musiałem używać instanceof i bawić się .constructorami. Anonimowe obiekty w wiekszosci przypadkow wystarczaja.
Generalnie dla mnie najlepszy jest sposob podany przez Szymona, a ze tego typu dziwolagi sie uzywa.. spójrzcie sobie na generatory klas w mootools na przyklad ;-)
Pozdrawiam
Hehe ;> To ja widać jestem purystą.
Z drugiej strony zacząłem dzisiaj pisać małą biblioteczkę na własny użytek i po 100 liniach kodu dochodzę od wniosku że dziwne konstrukcje tam po tworzyłem (niekoniecznie dobre, pewnie ;). Może to ten język tak wymaga ;)?