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) { … }
Názory k článku
Javascript a oblast působnosti proměnných - díl první
funkce
celé vláknoRe: funkce
celé vláknoI 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.
Re: funkce
celé vláknoSouhlas, zápis var test = function test(a) { … } má trošku jiný význam a není moc doporučeníhodný. Viz perfektní rozbor na toto téma: http://yura.thinkweb2.com/named-function-expressions/
Re: funkce
celé vláknoSpecifikace ří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.
Re: funkce
celé vláknoJe 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íž.
Re: funkce
celé vláknoAnonymní funkce na sebe může odkazovat pomocí arguments.callee. Tím je možná i rekurze.
Re: funkce
celé vláknoPochopitelně, 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.
Re: funkce
celé vláknoAni 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í).
Re: funkce
celé vláknoDí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).
Re: funkce
celé vláknoPardon, nepřečetl jsem si příspěvek Karla Fučíka nade mnou.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknojavascript 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…
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoJavaScript je zlý neni. To, že vám nevyhovuje, neznamená, že je špatný. Možná, že ste zlý hráč a neviete JavaScript. ;)
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoAsi 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:
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoKaž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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoC++ 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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoVaš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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknosuper 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ů.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoDěkuji. Jsem rád, že aspoň někdo účel tohoto článku pochopil.
Poslední příklad: zvyšuje o jedničku?
celé vláknoCituji 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.
Re: Poslední příklad: zvyšuje o jedničku?
celé vláknoJistě, 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í.
Re: Poslední příklad: zvyšuje o jedničku?
celé vláknoSelfpwn, 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ě.
Re: Poslední příklad: zvyšuje o jedničku?
celé vláknoNo +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.
Re: Poslední příklad: zvyšuje o jedničku?
celé vláknoMá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í.
Zacyklení při rekurzi
celé vlákno// 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(something[i].subSomething);// 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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoVelmi 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);“.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoJen 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;
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoMá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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoJežíš 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://developer.mozilla.org/en/Core_JavaScript1.5_Reference, 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.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoClovece, 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.
Uvaření globálních a IE
celé vláknoPokud 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
Hack s anonymkou
celé vláknoMyslí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;
… };
Re: Hack s anonymkou
celé vláknoVolání anonymní funkce není žádný hack :)
Re: Hack s anonymkou
celé vláknoPrvně 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é.
Re: Hack s anonymkou
celé vláknoHack 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 ,–)
Re: Hack s anonymkou
celé vláknoTento 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.
Re: Hack s anonymkou
celé vláknoAd 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.“
Re: Hack s anonymkou
celé vláknoNo, 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í.
Re: Hack s anonymkou
celé vláknoHmm, tak to mě napadá jen: (function(Array){
… })(AFramerowk.getModifiedType(Array, {
push: Array.prototype.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.
JavaScript díl 1 - proměnné
celé vlákno.. 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“.
:)
Re: JavaScript díl 1 - proměnné
celé vlákno… zbývá tedy jediná otázka: A proč to tedy nenapíšete jako článek a nenabídnete redakci?
Re: JavaScript díl 1 - proměnné
celé vláknoRe: JavaScript díl 1 - proměnné
celé vláknoŘekl bych, že překlad „prostředí“ moc zažitý nebude. Já ho třeba slyším prvně :)
Re: JavaScript díl 1 - proměnné
celé vláknoJá 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 :)
Re: JavaScript díl 1 - proměnné
celé vlákno„scope“ jako „prostředí“ opravdu zažité nebude, nicméně „scope“ jako „obor platnosti“ a „environment“ jako „prostředí“ zažité jsou.
Re: Javascript a oblast působnosti proměnných - díl první
celé vláknoČlánek není součástí seriálu, nelze se na něj dostat z ostatních dílu.
předání proměnné
celé vláknoZdraví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/javascript“>
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
Re: předání proměnné
celé vláknoNo 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);