Autor Zpráva
Suta
Profil
Moje otázka směřuje k principu fungování javascriptových frameworků na bázi níže uvedeného ukázkového kódu.

http://jslab.net/pub/jpw/sf/kod.core.html

Především bych byl rád za odpovědi na tyto otázky:

- domnívám se správně, že je takto postaven framework prototype.js ?
- jak je na tom jQuery? (bohužel jsem nenašel "prohlížitelný" kód)
- jaké výhody a nevýhody mi tento přístup může přinést?

Nejvíce mi pak pomůže odkaz na článek či sérii článků zabývající se touto problematikou, tedy zhruba tématem: "princip vytvoření metod aplikovaných přímo na dané objekty, jejich vytvoření a popis funkčnosti ". Bohužel jsem nic podobného nevygooglil.

Předem díky.
ah01
Profil
- domnívám se správně, že je takto postaven framework prototype.js ?
ano, viz http://www.prototypejs.org/learn/extensions

- jak je na tom jQuery?
jQuery funguje na jiném, poněkud méně invazivním, principu. Volání fce. jQuery ($) vrací wrapper objekt nad HTML elementem (tento objekt se jmenuje, kupodivu, jQuery). Ty pak dále nepracuješ s HTMLElementem, ale s jQuery objektem, který jej zapouzdřuje.

- jaké výhody a nevýhody mi tento přístup může přinést?
Vůči čemu?

Články na toto téma se mi teď žádné nevybavují, třeba někoho jiného nějaké napadnou.
Suta
Profil
Zmítám se v chaostu objektové orientovanosti javascriptu. Po téměř dvouměsíčních pokusech "přijít objektově orientovanému programování v javascriptu na kloub" musím přiznat, že mám nyní hlavu dvakrát větší a stojím na místě. To proto, že po napsání nového řádku kódu tento řádek brzy mažu s tím, že "se to přece má dělat jinak". Přepíšu jiným způsobem a opět mažu...

Naléhavě prosím o pomoc!

Spoustu rad a poučení jsem dostal v tomto tématu. Jelikož jsem se snažil přetransformovat své myšlení co nejvíce "objektově" (nikdy jsem objektové programování nepoužíval), cpal jsem do objektů naprosto vše. Objekty i metody. Uvedené téma rozebírá vytvoření třídy! pro fadeOut či fadeIn prvku. Tnz. že pro "metodu" se vytváří "objekt"... Předposlední příspěvek uživatele _es však končí těmito slovy:

Prečo používaš "ztmavnuti" ako objekt, logicky by to skôr mala byť metóda nejakého objektu.
... Skús nakresliť stmavnutie, nie stmavnutie niečoho, ale stmavnutie ako samostatnú entitu.
Veľmi zjednodušene, ak to je sloveso, alebo nejaká činnosť, tak by to mala byť metóda.


Ok. Souhlasím. Začal jsem tedy důsledně rozlišovat mezi objektem a metodou. Velmi zjednodušeně:

1. Vytvářím-li např. nová "inline" okna ve stránce, která mohou či nemusí mít lištu, obsah, ..., a vše bude mít různý obsah, vytvořím objekt pomocí instance třídy.
2. Vytvářím-li metodu, např. efekt fadeOut vytvořeného okna, snažím se využívat u jednoduchých situací klasické "obyčejné" funkce, u těch složitějších však nevím, kam sáhnout.

Již jednou zmiňovaný kódv prvním příspěvku tohoto tématu pak používá způsob, kdy jakýkoliv objekt můžu rozšířit o jakékoliv metody.

Mohl bych tedy projednou své trápení s "vytvářením metod" vyřešit tímto způsobem? Prvek, na nějž chci "všeobecnou" metodu definovat rozšířit pomocí metody "extend" a v této metodě pak definovat VŠECHNY své funkce/metody?

Snad někdo pochopí, co jsem se snažil říci. Bohužel existuje tolik způsobů, že se v tom skutečně strácím a nevím, která je ta "správná cesta"...
_es
Profil
Suta
JavaScript nemá také možnosti pre OOP ako niektoré iné jazyky.
Nemá žiadne "triedy".
A to používanie OOP v JavaScriptu sa len snaží simulovať lepšie možnosti iných jazykov.
Je to vidieť na odlišnom prístupe tých dvoch knižníc, každá s inými výhodami a nevýhodami.
Nie je preto žiadna najlepšia "správna cesta", treba použiť to, čo vyhovuje.
Suta
Profil
Dobře. Zeptám se ještě jinak. Při použití:

<script>
function $(element) {
....
    return($.extend(element);
}

$.extend = function(element) {
....
    element.mySetAttribute = function(parametr, value) {
    ....
    }
    element.myDalsiMetoda = function() { ... }
    ....
    element.dalsich_1000_metod....
}
var mujObjektNeboHTMLtag = $(document.getElementsByTagName("body")[0]); //pouze příklad
mujObjektNeboHTMLtag.zavolaniMetody().zavolaniDalsiMetody();
</script>

znamená, že při takovémto použití bude do objektu mujObjektNeboHTMLtag (v tomto případě tag body) přiřazeno všech 1000 metod a ten si je ponese na věky věků s sebou?
_es
Profil
Suta
znamená, že při takovémto použití bude do objektu mujObjekt_ci_HTMLtag (v tomto případě tag body) přiřazeno všech 1000 metod a ten si je ponese na věky věků s sebou?

Obrazne povedané áno.
Každý takto vytvorený objekt bude mať vlastných 1 000 vlastností/metod a každá bude obsahovať odlišnú funkciu.
Ak by si vytvoril 100 takých objektov, tak bude vytvorených celkovo 100 000 funkcií.
No zase to má výhodu, že sa môžeš v každej funkcii priamo odkazovať na premennú element, bez ohľadu na to, akým spôsobom bola funkcia spustená, čo by pri iných spôsoboch - napríklad cez prototyp nešlo.
Suta
Profil
_es
No zase to má výhodu, že sa môžeš v každej funkcii priamo odkazovať na premennú element
To ano, a je to něco, co se mi velmi! líbí. Nicméně vytvořit tímto způsobem celou knihovnu metod? A "inicializovat" pro jeden objekt 1000 metod, přičemž využiju prvních pět metod a "inicializovat" pro druhý objekt 1000 metod, přičemž využiju jiných 5? ...

Nicméně se mi tento způsob volání velmi zamlouvá. Bohužel nedokážu rozkódovat, zda-li prototype.js skutečně pracuje na stejném principu. Řekl bych, že pracuje mírně odlišně, ale nejsem schopen přijít na to "jak".

Prototype.js definuje metody v objektu Element (např., tedy ne všechny...):
Element.Methods = {
  addClassName: function(element, className) {
    ...
  },
  dalsiMetoda: function() { }
}


Funkce $() pak element rozšiřuje takto:

function $(element) {
  return Element.extend(element); // zde již nevím přesně, k čemu dochází...
}


Volání pak probíhá stejným způsobem, jako uvádím v příspěvku výše, tedy:

<div id="message" class=""></div>
$('message').addClassName('read');
//či také např.:
$(jinyElement).hide();


Nevím, jak je docíleno "spojitosti" mezi funkcí definovanou v Element.Methods a jejím zavoláním pomocí rozšiřující funkce $(). Dochází zde také u každého takto zavolaného objektu přes funkci $() k jeho rozšíření o xxx metod s tím, že v praxi využiji např. pouze jednu metodu?
ah01
Profil
Suta
Původně jsem začal psát mojí reakci jako vysvětlení kódu té metody Element.extend což by se pěkně protáhlo, protože zdrojový kód Prototypeu je poměrně složitý. Je to hlavně kvůli kompatibilitě mezi různými prohlížeči a to se týká i Element.extend.

Pokud píšeš své objekty, pravděpodobně při OOP používáš prototype. Můžeš tak rozšířit/upravit i jakékoliv jiné objekty, včetně nativních, jako je String, Function, Array, ….

Dalo by se předpokládat, že stejně můžeš manipulovat i s HTMLElement objektem (to je předek všech elementů DOM). Ono to jde, ale bohužel ne všude – IE (starší než IE8) takto přidané metody ignoruje. To je hlavním obsahem toho původního vlákna, ze kterého pochází odkazovaný kód.

Jak tedy funguje Element.extend? V principu se Prototype pokusí zjistit, jestli je možné přímo rozšířit prototype HTMLElementu, pokud ano, udělá to a metoda Element.extend pak nedělá nic. Pokud to ale nejde, funguje Element.extend tak jak je ukázáno výše, tedy do elementu přidá všechny potřebné metody. Tím je zajištěno, že tato méně efektivní metoda je použita jen u prohlížečů, kde to prostě jinak nejde.

Aby to bylo co nejefektivnější a nejlépe se využili specifické vlastnosti toho, či onoho prohlížeče, je implementace velmi komplikovaná.

Pokud se ti tento postup líbí a je ti sympatický, používej Prototype (nebo MooTools, tam je to obdobné). Dál to moc nepitvej, protože se v tom nejspíš utopíš. Prostě věř, že autoři Prototype Frameworku ví, co dělají, a kód mají napsaný tak, aby byl co nejefektivnější.
Suta
Profil
ah01
Přesná odpověď a vysvětlení mé otázky, díky. Nyní principu "zapouzdření" metod tak, jak je provádí framework prototype.js rozumím. Vypadá to, že se brzy přidám k řadám těch, jež využívají prototype.js, jQuery.js či jiný framework. Nicměné...

Zůstává ještě jedna nezodpovězená otázka. Jde tedy přesně o:

V principu mi jde pouze o odpověď, jak tedy správně vytvořit a použít metodu?
Prečo používaš "ztmavnuti" ako objekt, logicky by to skôr mala byť metóda nejakého objektu. (reakce uživatele _es, jehož příspěvky mi samozřejmě také velmi pomohly)

Prakticky:
1. Mám jakoukoliv část stránky (dejme tomu vyberu "tento" konkrétní div)
2. Tag div (s nímž dále pracuji) je již sám o sobě objekt.
3. Chci na něj aplikovat metodu fadeOut, či fadeIn, či jakoukoliv jinou..
4. Původně jsem takovéto operace prováděl vytvořením nové instance třídy Fade, jíž jsem poslal daný objekt (odkaz na div) a na dalších řádcích jsem pak mohl volat metody této instance, tedy:
    novaInstance = new Fade(mujDiv);
    novaInstance.fadeOut();

5. Tento postup je "údajně" nesprávný, jelikož pro metodu vytvářím nový objekt "novaInstance".

To mě pěkně rozhodilo. Nejprve několik dnů v tomto foru vytváříme třídu Fade, jež v sobě nese metody umožňující práci s různými efekty přechodu elementu, a poté je mi sděleno, že je to "metoda" a neměla by být vytvářena jako objekt.

Proto mé tápání, jak tedy "správně" vytvořit a zavolat metodu na daný element... Stále nevím.
_es
Profil
Suta
Problém je, že ti chýbajú aspoň základné vedomosti o OOP, na webe o tom určite nájdeš nejaké články, alebo aj v knihách, aspoň tie základné myšlienky ako napr.:http://books.google.com/books?id=CRpMH-Ui7HkC&lpg=PA241&dq=oop&lr=lang_cs&as_drrb_is=q&as_minm_is=0&as_miny_is=&as_maxm_is=0&as_maxy_is=&num=100&as_brr=0&hl=sk&pg=PA240#v=onepage&q=oop&f=false. Snaž sa nájsť literatúru o OOP všeobecne, nie k nejakému konkrétnemu jazyku.
Ďalej chceš vytvárať zložité skripty na úrovni tých frameworkov, no chýbajú ti niektoré vedomosti o syntaxe a vlastnostiach JavaScriptu na to potrebné. V inej téme som ti dal odkaz na jednu veľmi dobrú knihu o tom, v češtine, ak môže byť aj v angličtine, tak zoženieš alebo "zoženieš" aj novšie vydanie.
Suta
Profil
_es
Dobrá. Můžeš mi tedy ještě okomentovat následující?
To mě pěkně rozhodilo. Nejprve několik dnů v tomto foru vytváříme třídu Fade, jež v sobě nese metody umožňující práci s různými efekty přechodu elementu, a poté je mi sděleno, že je to "metoda" a neměla by být vytvářena jako objekt.
_es
Profil
Suta
Ono sa to dá použiť aj tak, môže to byť aj dobre funkčné, len to veľmi nezodpovedá tomu "OOP" prístupu.
Suta
Profil
_es
A právě proto ona otázka, jak v javascriptu správně objektově vytvořit metodu, kterou aplikuji přímo na daný element. Bez frameworku. Tedy.. jde-li to jednoduše.

Mno nic. Myslím, že základy objektového programování znám. Také jsem již během posledních 14 dnů přečetl další dvě knížky zabývající se objektově orientovaným programováním. Nicméně při implementaci objektově orientovaného přístupu v javascriptu se mi staví vlasy na hlavě...

Vracím se ke klasickým funkcím, vypadá to, že na víc nemám.

Díky všem za rady.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: