Autor Zpráva
tomascejka
Profil *
Ahoj, tak procitam web:
(1)Object.prototype is verboten,
(2)Object.prototype is erlaubt,
(3)Object.prototype is erlaubt,
(4)Classical Inheritance in JavaScript

A nejsem si jist, jak je to s tim, ze mohu/nemohu rozsirovat nativni objekty v javascriptu. V jednom sem si jisty, ze objekt Object je nevhodne rozsirovat, a to at funkcema nebo promennymi do objektu prototype.

a) Mylim se,ze Object.prototype lze rozsirovat, alespon funkcemi, nikoli hodnotami, kt. pak dedi vsechny objekty?
b) Anebo rozsirovat ano, a to pouze metody do prototypu Array,String,Function

Nejsem si jist, a nedokazu dohlednout, zda v otazce b je to spravne rozsirovat tyto objekty. U otazky a bych rekl, ze tento zpusob mi neni vlastni a nedelal bych to, ale existuji pripady, kdy je to prinosem?

Dle meho nazoru a momentalniho know-how, Object nerozsiruji vubec a podrizene objekty take ne. Vzdy kdyz potrebuji metodu u objektu, tak si jej vytvorim a metodu mu naimplementuji, ale nikdy ne na predkovy - nativnich fci.

c) Unika mi tim neco? Mylim se, kdyz reknu, ze je to bezpecne, anebo sem konzervativni?

Diky

TC
tomascejka
Profil *
Jen snad dodam, ze v odkaze 2, je pod clankem ve foru poznamka od Nicolas Zakas, kt. rika (snad sem to prelozil dobre), ze rozsirovat Object (anebo jenom podrizene nativni objekty) je vhodne, jenom kvuli dedicnosti. A to tak, ze funkce do prototypu a promenne/hodnoty do vlastnosti objektu.

Zde vaham. Poradte, myslim si, ze odpoved na toto tema bude velkym prinosem pro kazdeho kdo koduje v Javascriptu

TC
ah01
Profil
Rozšiřovat můžeš cokoli. Myslím tím přidávat vlastnosti do prototype daného objektu a je jedno zdali přidáváš řetězec, pole nebo funkci, je to stále to samé. Je ale rozdíl mezi tím co můžeš a co bys dělat neměl. Problém při rozšiřování nativních objektů je totiž v tom, že tyto změny se projeví všude.

První důsledek je při použití for-in. for-in je cyklus přes všechny vlastnosti objektu a to i těch které objekt má v prototype (ty, které zdědí). A to je hlavní důvod proč nerozšiřovat nejvyšší objekt Object. Od něj totiž dědí všichni, a tedy pokud budeš procházet pomocí for-in cokoli, automaticky tam máš vlastnosti, které sis dodefinoval do Object. Pokud budeš používat for-in měl bys automaticky psát něco takového
for(var i in list)
{
  if(!list.hasOwnProperty(i)) continue; // pokud je i z prototypu, pokračuj na další položku
  tělo for-in
}

to je, ale trochu otrava.

Druhý důsledek platí hlavně v případě, že budeš chtít svůj skript zveřejnit. Například napíšeš skvělý revoluční Lightbox a budeš ho chtít poskytnout světu. Určitě je ti jasné co se stane, když bude mít nějaký uživatel na stránce i jiný skript, který bude třeba používat for-in a nebude tam mít ten otravný řádek s if… Může se taky stát, že i on bude mít přidané nějaké vlastnosti do nativních objektů a náhodu se shodnete na jméně, ale funkčnost bude jiná…

Z toho důvodu je dobré myslet na ostatní a neměnit nativní objekty.

Naopak pokud budeš psát skript jen pro sebe je ovlivňování nativních objektů velmi příjemné. JS je poměrně strohý jazyk, co se týče různých užitečných vestavěných funkcí. Ale je to jazyk dynamický, tak proč toho nevyužít.



A teď konkrétně k tvým poznámkám:

Ad a) Je jedno zdali rozšiřuješ hodnotou (vlastnost) nebo funkcí (metoda) v JS je to jedno a to samé. Funkce je totiž taky objekt a tak se s ní i pracuje.

Ad b) Jak jsem psal, rozšiřovat můžeš vše. Je třeba mít ale na paměti, že rozšiřuješ něco, co používají všichni. Pokud tedy píšeš nějaký univerzální skript, který bude používat více lidí, je lepší se tomu vyhnout úplně. Sahání pak na Object je lepší se vyhnout vždy, musíš už opravdu vědět, co děláš a mít k tomu pádný důvod.

Pokud přidáš metodu přímo do prototype, existuje pouze jednou. Pokud ji přidáš přímo objektu, existuje u každého zvlášť. Z paměťových důvodů je rozumně vytvářet ji pouze jednou. Nepochopil jsem, jestli nerozšiřuješ pouze nativní objekty nebo nepoužíváš prototype vůbec (první je rozumné – viz výš, druhé už moc ne)?

Mimochodem Nicholas C. Zakas je autor knihy Professional JavaScript for Web Developers, kterou ti vřele doporučuji přečíst. Když už jsme u knih, vyšel nedávno český překlad knihy od Johna Resiga (to je autor jQuery) Pro JavaScript Techniques, česky se to jmenuje (bůhví proč) JavaScript a Ajax. To je kniha pro pokročilé javaskriptaře, vřele doporučuji.

Nepsal jsem moc konkrétně ale spíš obecně k problému. Snad jsem ti trochu pomohl blíže pochopit o co jde. Pokud ne, ptej se dál…



PS: u pramene (3) na který odkazuješ je popsaná jaká si univerzální funkce, která řeší problém rozšiřování Object. Důrazně nedoporučuji ji používat. Osobně bych se ji nedotkl ani klackem. Je to sice zajímavý experiment, ale je to ten nejhorší možný způsob jak to řešit. Pro vysvětlení, autor získá zdrojový text funkce jako řetězec, ten docela komplikovaným způsobem upraví a výsledek spustí jako JS kód. Snad nemusím dále psát jak nebezpečný způsob to je…
tomascejka
Profil *
Vyborne,

Takze rozsireni nativnich objektu muze vest ke kolizi s ostatnimi scripty - to je pro nasazeni scriptu pro volne pouzivani velmi nebezpecne, tak me napada dalsi otazka.

Jakto resi frameworky Prototype a Mootools, kt. jsou znamy tim, ze rozsiruji nativni objekty?

a) Jsem tedy odsouzen ke znalosti jejich kodu?!

b) for-in smycka A.hasOwnProperty testuje pouze ty vlastnosti, kt. primo patri objektu A? Chapu to dobre, ze vraci false, pro vsechny vlastnosti, kt. zdedi od predka a to vcetne, vlastnosti, kt. predek dedi od sveho nadrazeneho objektu atd.



Pochopil sem nasledujici vety spravne:
Pokud přidáš metodu přímo do prototype, existuje pouze jednou. - znamena to, ze objekt prototype, je vytvoren pouze jednou, a reference na metody/vlastnosti maji zivotnost od deklarace tohoto prototypu u rodicovskeho objektu az po onunload eventu?

Pokud ji přidáš přímo objektu, existuje u každého zvlášť. Z paměťových důvodů je rozumně vytvářet ji pouze jednou. - nemylim se, ze ji lze povazovat za statickou metodu objektu?

Dalsi otazky mam:

A) jak funguje prototype objekt v pripade, ze chci dedit od jineho objektu, a jak ziskam referenci na predka? Pomineme, ze vlastnosti
objektu Clovek, muze mit az jeho potomek Osoba, ale jenom pro tento priklad uvadim tento vztah:

// JavaScript Document
     var Clovek = function (pohlavi) {
          this.pohlavi = pohlavi;
          this.vek = undefined;
          this.setVek = function (vek) {
              this.vek = vek;
          }
          this.getVek = function () {
              return this.vek;
          }
     };
     var Osoba = function (pohlavi,jmeno,prijmeni) {
          this.jmeno = jmeno;
          this.prijmeni = prijmeni;
          this.prototype = new Clovek(pohlavi);
          this.toString = function () {
              alert(/*chci pouzit metodu predka - getVek*/);
          };
     };

     var person = new Osoba("tomas","cejka");
     person.setVek(18);//v tuto chvili vim, ze tato metoda je podedena, ale jak dosahnu na predka objekt Clovek
     person.toString();


Jak nyni dosahnu na objekt Clovek - metodu getVek?
tomascejka
Profil *
Ha, spletl sem se... myslim,ze je to na delsi povidani. presunu to do jineho vlakna.... vyse uvedena otazka ma samozrejme jednoduche reseni, spatne polozena otazka a ke vsemu sem ji ukazoval na spatne prikladu... v ramci dokonceni vlakna reseni

     var Osoba = function (pohlavi,jmeno,prijmeni) {
          this.jmeno = jmeno;
          this.prijmeni = prijmeni;
          var parent = new Clovek(pohlavi);
          this.prototype = parent;
          this.toString = function () {
              alert(parent.getVek());
          };
     };

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:

0