48 komentářů k článku Javascript a oblast působnosti proměnných – díl první:

  1. Dero

    funkce

    var test = function test(a) { … }

    V sekci o funkcích je podobný kus kódu, správně ale nejspíš má být takhle (?): var test = function (a) { … }

    1. Aleš Roubíček

      Re: funkce

      I tento zápis je správný. V prvním případě, se do proměnné test přiřazuje pojmenovaná funkce, v druhém případě funkce anonymní. Výhodou prvního případu je, že se v některých debugovacích nástrojích mnohem lépe orientuje v call stacku.

    2. ah01

      Re: funkce

      Specifikace říká, že pokud použiji výraz function identifikator(){ … }, tak identifikator bude dostupný pouze uvnitř této fce. (třeba pro potřeby rekurze). Takže následující kód způsobí chybu (IE toto nerespektuje). 

      var verejny_nazev = function soukromy_nazev(){ … };
      soukromy_nazev(); // Chyba

      Nemyslím si, že by toto použitelné v praxy (navíc, když v IE to nefunguje). Zmiňuji to kuli uvedenému zápisu var test = function test(a) { … }. Pokud bych později potřeboval přejmenovat tuto fci. a jméno změnil jen na jednom místě, můžu se dostat do problémů.

      PS: toto uvádí i článek, který zmiňuje Karel Fučík. Ono těch zájímavostí/zá­ludností ohledně deklarace funkce je víc, takže pokud vás to zaujalo, přečtěte si ho.

    3. Petr StaníčekAutor příspěvku

      Re: funkce

      Je to hlavně kvůli tomu, co níže poznamenává Adam Hořčica. Pokud je funkce anonymní, tak na sebe zevnitř nemůže odkazovat a nelze např. pracovat s rekurzí. A použít jiné veřejné a jiné privátní jméno zase můžýe sestřelit některé hloupější prohlížeče, takže se to moc nedoporučuje. Proto píšu, že ekvivalentní jsou právě tyhle dva zápisy, jsou si co do funkce a významu asi nejblíž.

        1. Petr StaníčekAutor příspěvku

          Re: funkce

          Pochopitelně, ale každý jistě poznal, že mluvím o referenci přes název. Používání function.callee (nebo call či apply nebo práce s polem arguments) je poněkud pokročilejší a nemůžete to přeci chtít po začátečníkovi nebo mírně pokročilém, kterému je tento článek určen.

          1. karf

            Re: funkce

            Ani na okamžik jsem nepochyboval, že by Petr Staníček neznal arguments.callee. Ovšem jako začátečník bych si z věty „Pokud je funkce anonymní, tak na sebe zevnitř nemůže odkazovat a nelze např. pracovat s rekurzí.“, ať už byla myšlena v jakémkoli kontextu, nejspíš odnesl zcela jednoznačný a zcela mylný závěr. Proto moje poznámka (nebyla myšlena jako rejpání).

      1. Dero

        Re: funkce

        Díky za odpověď, pixy, šlo mi jen o to, zda ses neupsal. Přiřazovat pojmenovanou funkci proměnné téhož jména není totiž v praxi příliš běžné, proto jsem se nad tím pozastavil. Nicméně rekurze v anonymních funkcích nepředstavuje problém (arguments.callee).

  2. blizz.boz

    Re: Javascript a oblast působnosti proměnných - díl první

    javascript je zlý jazyk so zlým návrhom. ešteže existujú projekty ako Script# ktoré umožnujú písť JS aplikácie v jazyku C#.

    a inak perfektný článok…

    1. Aleš Roubíček

      Re: Javascript a oblast působnosti proměnných - díl první

      JavaScript je zlý neni. To, že vám nevyhovuje, neznamená, že je špatný. Možná, že ste zlý hráč a neviete JavaScript. ;)

      1. blizz.boz

        Re: Javascript a oblast působnosti proměnných - díl první

        Asi pred tromi rokmi som vytvoril Ajaxovú open source komponentu JoomlaComment! ktorá sa dnes používa na celom svete, ale keď som robil klientskú časť tej komponenty tak som celý čas nadával a veľa nechýbalo k tomu aby som počítač hodil o zem, JavaScript je ešte vačšia prasárna ako PHP. Že je JS zlý jazyk ukazuje aj tento článok citujem:

        „Jedním z největších zel Javasciptu je skutečnost, že explicitní deklarování proměnných není povinné. Nicméně jeho nepoužívání může vést k řadě problémů a skrytých chyb a je dobrým zvykem slušného programátora vařit úplně každou proměnnou – především právě proto, aby měl zcela jasno v mezích její platnosti.“

        inak odporúčam tento blog s poetickým názvom: Javascript ZLO 2.0:

        1. Aichi

          Re: Javascript a oblast působnosti proměnných - díl první

          Každému co jeho jest. Je zlo C++, že nemá garbage collector? Uržitě je a stejně ho používá hodně programátorů. To že pán z toho blogu nechápe javascript je jeho problém. JavaScript určité konstrukce umožňuje a je nutné se je naučit, pokud ho chceš používat. Takhle můžeš potom pranýřovat Rupy, Smalltalk a další … Nicméně většinou použiješ takový kód, kterému věříš a máš ozkoušeno, že ti nemění funkčnost pod rukama.

          1. blizz.boz

            Re: Javascript a oblast působnosti proměnných - díl první

            C++ je jazyk určený na tvorbu systémov driverov atď, je to dobrý jazyk len je trochu náročné na čas v ňom programovať. ale pokiaľ viem managed C++ už má garbage collector.

            A pán z toho blogu veľmi dobre chápe JavaScript, veď v tých článkoch práve poukazuje na slabiny tohto jazyka, podrobne ich tam popisuje. JavaScript je zlý jazyk, každý kto v ňom musel naprogramovať vačšiu aplikáciu naň nadával, JS vznikal postupne a je to nekonzistentný zlepenec plný chýb, každý prehliadač ho podporuje ináč a písať JS bez použitia nejakého sofistikovaného Frameworku je doslova peklo.

            1. Aichi

              Re: Javascript a oblast působnosti proměnných - díl první

              Vašemu komentáři se nedá vůbec věřit a to proto, že používáte slovo každý. Já si třeba na JavaScript nestěžuji. Co vám příjde nekonzistentní? Jaký jazyk nevznikal postupně? pokud vím, tak C/C++ má několik norem, jak vývoj postupoval. Jaké chyby v JavaScriptu máte na mysli? Nemyslíte tím spíš jeho implementace? Mě se zdá, že na „takové to domácí skriptování“ moc rozdílů mezi prohlížeči implementujícími JavaScript nenarazíte.

  3. mykhal

    Re: Javascript a oblast působnosti proměnných - díl první

    super užitečný článek pro člověka, který javascript používá jako nástroj a neměl zatím čas se pohroužit do jeho teoretických základů.

    1. Petr StaníčekAutor příspěvku

      Re: Javascript a oblast působnosti proměnných - díl první

      Děkuji. Jsem rád, že aspoň někdo účel tohoto článku pochopil.

  4. v6ak

    Poslední příklad: zvyšuje o jedničku?

    Cituji poslední příklad:

    function test() {
    function plus(x) { return x++ }
    alert( plus(1) );
    } test(); alert( plus(1) );

    Opravdu funkce plus zvyšuje hodnotu o jedničku? Zvyšuje to jen uvnitř (implementační detail), ale navenek je to úplně jedno: proměnná x není volána odkazem (to v JS asi ani nejde) a postfixový operátor vrací původní hodnotu konvertovanou na číslo.

    Samozřejmě, poslední řádek způsobí chybu, s tím souhlasím.

    1. Petr StaníčekAutor příspěvku

      Re: Poslední příklad: zvyšuje o jedničku?

      Jistě, nechtěl jsem zabředávat do detailů, protože tady zrovna jde o něco jiného, nač je třeba se soustředit, takže jsem to nenapsal exaktně přesně. Funkce plus() zvýší (v tomto případě) o jedničku hodnotu své interní, lokální proměnné „x“ a vrátí její hodnotu (zápis return x++ je ekvivalentní zápisu  x = x+1; return x).

      Ale s tím „voláním odkazem“ to tak jednoduché není, ne že to Javascript nemá – má to, ovšem probíhá to automaticky a programátor to nemá pod kontrolou. Zjednodušeně řečeno: skaláry se do funkcí v JS předávají hodnotou, objekty referencí.

      1. Petr StaníčekAutor příspěvku

        Re: Poslední příklad: zvyšuje o jedničku?

        Selfpwn, pardon! Zápis return x++ NENÍ ekvivalentní zápisu x = x+1; return x, to by to muselo být return ++x. Omlouvám se, napříště se musím na komentáře více soustředit a číst to po sobě.

      2. v6ak

        Re: Poslední příklad: zvyšuje o jedničku?

        No +1 místo ++ by tomu neubralo na srozumitelnosti, spíše naopak. Ad volání odkazem: ve chvíli, kdy do této proměnné něco přiřadím, není tím ovlivněno nic mimo funkci. Tomu neříkám volání odkazem. Je to vlastně stejně jako u Javy, ta taky nemá volání odkazem, i když můžu samozřejmě předat referenci na objekt.

        1. Petr StaníčekAutor příspěvku

          Re: Poslední příklad: zvyšuje o jedničku?

          Máte pravdu, prosté +1 je zde lepší a méně matoucí. Hlavně v tom kódu VŮBEC nejde o to, co ta funkce dělá, má jen demostrovat její samotnou existenci. Já tam plácnul prvním, co mě napadlo, a pak jsou z toho takováhle mrzení.

          Požádal jsem redakci o opravu, místo return x++ by tam napříště mělo být jen return x+1. Děkuji za pochopení.

  5. v6ak

    Zacyklení při rekurzi

    // použití v praxi Doplním, že klasický for cyklus v kombinaci s globální proměnnou místo lokální může znamenat zavyklení při rekurzi:

    function myFunc(something){

    // žádné var i!
    for(i=0; i<something.lenght; i++){

    if(…){
    myFunc(somethin­g[i].subSomet­hing);// rekurze
    };

    };
    … }

    Toto může vést ke snížení hodnoty i v průběhu cyklu a často následně k zacyklení. Navíc zde je pak provedeno část iterace s jinou hodnotou i, což způsobí další nepořádek.

  6. Michal Augustýn

    Re: Javascript a oblast působnosti proměnných - díl první

    Velmi pěkný článek. Jen bych si dovolil malou poznámku k této větě: „Pokud je proměnná deklarována na nejvyšší úrovni, tedy přímo v dokumentu, mimo tělo nějaké funkce, stává se tímto okamžikem proměnnou globální a je dostupná z kteréhokoli místa kódu.“.

    Použití slova „dokument“ považuji za velmi nešťastné. V JavaScriptu je tou nejvyšší úrovní globální objekt. Co je tím globálním objektem pak už záleží na konkrétním nasazení JavaScriptu. Pokud se máme bavit o prohlížečích, tak to je objekt „window“, nikoliv „document“. Zkuste si „alert(this === window);“ a „alert(this === document);“.

    1. Daniel Steigerwald

      Re: Javascript a oblast působnosti proměnných - díl první

      Jen bych dodal, že „mimo tělo nějaké funkce“ je rovněž nešťastná formulace, jakoby globální proměnná nešla definovat přiřazením na globální objekt, např. window.iamGlobal = true;

      1. Petr StaníčekAutor příspěvku

        Re: Javascript a oblast působnosti proměnných - díl první

        Máte pochopitelně pravdu, ony se někdy holt srozumitelnost pro začátečníky a exaktní přesnost pro odborníky trochu tlučou. Z hlediska příležitostného programátora je „globální objekt“ a „úroveň HTML dokumentu“ totéž a do této míry jsem komplikovat ty věci už opravdu nechtěl. Ale asi by stálo za zvážení doplnit ještě kapitolku o vazbě mezi globálními proměnnými a objektem window a nebezpečí předefinování jejích vlastností a metod.

        1. Daniel Steigerwald

          Re: Javascript a oblast působnosti proměnných - díl první

          Ježíš Pixy, přestaň používat zavádějící zmatečnou kvaziterminologii, vycházející s podivných překladů DOM pojmů, jejichž význam článek navíc ne zcela jasně objasňuje. :)

          Co to proboha je „úroveň HTML dokumentu“? Chvíli sem si lámal hlavu, než sem přišel na to odkud vítr vane… Patrně půjde o script ve stránce? A co když je script externí? Dle tvé logiky by šlo o „úroveň externího souboru“ ;)

          Vřele doporučuji používat anglické pojmy, z českým překladem v závorce. Chudák začátečník, poté co překoná tvých x kapitol věnovaných varu, deklaraci a jejich romantickému vztahu k objektu window, bude totálně zmaten, až se začte například do https://develo­per.mozilla.or­g/en/Core_JavaS­cript1.5_Refe­rence, neb zpětným překladem se správného termínu nedobere. Chápu, že sis potřeboval někam sesumarizovat svoje zkušenosti s javascriptem, ale nevím jestli je zdroják vhodné místo ;)

          Tvrdit, že anonymní funkce se nedá použít v rekurzi prozrazuje hlubokou neznalost javascriptu.

      2. KLoK

        Re: Javascript a oblast působnosti proměnných - díl první

        Clovece, nechcete jit zakum pate tridy vysvetlovat, ze soucet uhlu trojuhelniku je pravdepodobne 180 stupnu? Tedy za predpokladu, ze je nakreslen v euklidovske rovine a ze to muze byt take o neco vic nebo min v zavislosti na prostoru ve kterem se pohybujem.

        Ja jsem presel k webovym aplikacim z jazyka C, odkud si clovek prinasi urcite navyky ktere nejsou ke skode. Napr. deklarace promenych pred prvnim pouzitim. Z JS pouzivam vyhradne jQuery a jeho rozsireni. Diky tomu jsem na problemy popisovane p. Stanickem zatim nemel to „stesti“ narazit.

        A diky za takovy clanek, ktery naprosto srozumitelnou formou osvetli, ze muze k takovemu problemu dojit a hlavne za vysvetleni co ho muze zpusobit.

  7. Leoš Ondra

    Uvaření globálních a IE

    Pokud globální proměnné neuvaříte, pak si přiděláte problémy hlavně v IE. Kód

    <p id=„x“>Odstavec v html</p>

    <script …> x = 5; </script>

    způsobí chybu Objekt tuto vlastnost nebo metodu nepodporuje, a pokud budete pátrat jaký proboha objekt, pak zjistíte, že ho za vás iniciativně vytvořil IE sám – je jím odkaz na element s id=„x“. Pokud se kod zmeni na

    var x = 5;

    nebo

    var x; x = 5;

    pak máte o problém míň.

    Leo

  8. v6ak

    Hack s anonymkou

    Myslím, že v tomto kontextu můžeme zmínit tento hack: (function(){
    var foo;
    … })(); Funguje to obdobně jako toto v Javě, C, C++, …: {
    type foo;
    … };

      1. v6ak

        Re: Hack s anonymkou

        Prvně je potřeba definovat „hack“ a pak můžeme diskutovat o tom, zda to je nebo není hack. Pro mě je to nezamýšlené použití, byť může být v souladu s normou. Každopádně toto využití považuji za užitečné.

        1. Daniel Steigerwald

          Re: Hack s anonymkou

          Hack je něco, co něco (jiného) „znásilňuje“ :) Tvůj příklad je velmi užitečný a bylo dobré ho zmínit, výhrady sem měl pouze k použití pojmu „hack“.

          Pro upřesnění, za hack považuji třeba resetování dontEnum attributu na nativních funkcích, například:

          var push = Array.prototype.push; delete Array.prototype.push Array.prototype.push = push;

          K čemu to je dobré? for in na Array.prototype náhle najde i push funkci, což se hodí při vytváření array-like objektů. Více, až zveřejním svůj framework ,–)

          1. v6ak

            Re: Hack s anonymkou

            Tento konkrétní hack nepovažuju za šťastné řešení – použití kódu, který vyžaduje hack spolu s kódem, který se spoléhá na standardní chování, je prakticky nemožné. Lepší by bylo napsat nástroj, který umožní procházet i tyto položky, např pomocí for(i in MyTool.Array)… . Název MyTool jsem použil, protože se mi nechtělo hledat nic lepšího. Důležité je, že standardní chování je zachováno. Jinak já opravdu neznám žádnou definici slova hack. Pokud někdo má, rád ji uvítám.

            1. Martin Malý

              Re: Hack s anonymkou

              Ad hack – definice z Wikipedie nestačí? „Hack has several related meanings in the technology and computer science fields. It may refer to a clever or quick fix to a computer program problem, or to what may be perceived to be a clumsy or inelegant (but usually relatively quick) solution to a problem. The term is also used to refer to a modification of a program or device to give the user access to features that were otherwise unavailable, such as DIY circuit bending.“

            2. Daniel Steigerwald

              Re: Hack s anonymkou

              No, jen dodám, že Sheer framework umožňuje modifikaci prototype všech nativních metod, přesto nijak neovlivňuje prostředí ve kterém běží. Tedy, všechny finesy PrototypeJS a Mootools frameworků, jenž modifikují prototype, avšak s žádným negativním dopadem na prostředí ve kterém běží. Prostě znám způsob, jak ohnout js jakkoliv, aniž by se bylo třeba obávat dopadů na ostatní kód. Tohle je hack. Volání anononymní metody hack není.

              1. v6ak

                Re: Hack s anonymkou

                Hmm, tak to mě napadá jen: (function(Array){
                … })(AFramerowk­.getModifiedTy­pe(Array, {
                push: Array.prototy­pe.push }));

                Možná existuje ještě něco jiného (nemyslím obdoby tohoto řešení na stejném principu), ale to neznám.

                V každém případě změna lokálního prostředí nebude škodlivá, to je pak něco jiného.

  9. Daniel Steigerwald

    JavaScript díl 1 - proměnné

    .. abych jen nekybicoval, jak bych to napsal já.

    Proměnou deklarujeme pomocí klíčového slova „var“, např.

    var bla = 'foo'.

    To var tam dávejte vždycky, poběží to sice bez toho, ale koledujete si zbytečně o problémy, protože proměnná tak bude globální a jelikoz Internet Explorer propaguje všechny ID elementů do globálního scope, může dojít ke kolizi názvů.

    Funkci deklarujete bud tak, ze ji pojmenujete:

    function foo() {}

    nebo priradite anonymní funkci deklarované proměnné:

    var foo = function() {}

    Kombinace obou přístupů je možná, ale zbytečná.

    Chcete-li 100% crossbrowser přístup, tak na pojmenované funkce zapomeňte, prohlížeče je interpretují rozdílně. Třeba safari nadeklaruje i tuto funkci:

    if (false) function foo(){};

    takže vždy psát:

    var foo = function() {};

    Jakmile proměnou deklarujete, můžete ji používat a odkazovat se na ní. Jaká je její viditelnost? Proměnná je viditelná v celém scope(rozsahu) funkce, ve které je definovaná. Pokud není definovaná ve funkci, je viditelná všude, tedy globální.

    Co to znamená scope? Všechno uvnitř nějaké funkce:

    var foo = function() { // tady je scope foo var bla = function() { // tady je scope bla } }

    Scope funkce, jak je vidět, tedy může být zanořený. Zanořovat lze do alelůja, vydáme-li se však opačným směrem, skončíme u objektu window (pakliže se bavíme o javascriptu v prohlížečích).

    Další díl: co je to „context“ a jak funguje „this“.

    :)

    1. Martin Malý

      Re: JavaScript díl 1 - proměnné

      … zbývá tedy jediná otázka: A proč to tedy nenapíšete jako článek a nenabídnete redakci?

    2. Timy

      Re: JavaScript díl 1 - proměnné

      Není zažitým překladem scope „prostředí“? Nebo je to zažité jen u nás na škole? :-) Klasicky u nás říkáme lexikální prostředí (lexical scope) a lexikální uzávěr (lexical closure).

      1. Borek Bernard

        Re: JavaScript díl 1 - proměnné

        Řekl bych, že překlad „prostředí“ moc zažitý nebude. Já ho třeba slyším prvně :)

        1. Daniel Steigerwald

          Re: JavaScript díl 1 - proměnné

          Já jsem oba pojmy už slyšel, na „úzávěr“ se totiž nedá zapomenout :) Každopádně google vrací na „lexikální prostředí“ 18 výsledků, takže asi moc zažitý skutečně nebude :-) „úroveň HTML dokumentu“ pana Staníčka pak odkazy dva :)

        2. povinná

          Re: JavaScript díl 1 - proměnné

          „scope“ jako „prostředí“ opravdu zažité nebude, nicméně „scope“ jako „obor platnosti“ a „environment“ jako „prostředí“ zažité jsou.

  10. PetrP

    Re: Javascript a oblast působnosti proměnných - díl první

    Článek není součástí seriálu, nelze se na něj dostat z ostatních dílu.

  11. Johny_S

    předání proměnné

    Zdravím, v první řadě bych chtěl poděkovat za článek. V JS jsem začátečník, zkoušel jsem proto jednoduchý příklad.

    <script type=„text/ja­vascript“>

    var a;

    function text() {
    a = 5;
    }
    </script>

    Není mi jasné proč se do proměnné „a“ deklarované před funkcí, se v těle funkce nepřiřadí hodnota „5“. Tuto hodnotu bych potřeboval použít i v jiných funkcích. Funkci volám při načtení stránky.

    Díky za odpověď JS

    1. v6ak

      Re: předání proměnné

      No nevím, co děláš, ale toto mi podle očekávání vypíše undefined a 5:

      var a;

      function text() {
      a = 5;
      };

      alert(a);
      text();
      alert(a);

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=3060