<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code42 &#187; JavaScript</title>
	<atom:link href="http://code42.pl/kategoria/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://code42.pl</link>
	<description>Wielkie Pytanie o Życie, Kod i całą resztę</description>
	<lastBuildDate>Wed, 25 Jan 2012 14:16:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</title>
		<link>http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/</link>
		<comments>http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 13:44:10 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[gtug]]></category>
		<category><![CDATA[meet.js]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[ssjs]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1306</guid>
		<description><![CDATA[W listopadzie zapraszałem Was na pierwsze wrocławskie edycje Meet.JS i GTUG. Dzisiaj jesteśmy już po drugiej edycji każdej z imprez. Na obu &#8211; Meet.JS Wrocław i GTUG Wrocław przedstawiałem ten sam temat &#8211; Node.JS. Na szczęście okazało się, że zbiór wspólny uczestników był bardzo mały i chyba nawet nikt nie przysnął :). Poniżej link do [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/' rel='bookmark' title='Wrocław wita JavaScript – Meet.JS i Wrocław GTUG'>Wrocław wita JavaScript – Meet.JS i Wrocław GTUG</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/' rel='bookmark' title='Node.js i middle-end – przenośny kod i emulacja przeglądarki'>Node.js i middle-end – przenośny kod i emulacja przeglądarki</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>W listopadzie <a href="http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/">zapraszałem Was na pierwsze wrocławskie edycje Meet.JS i GTUG</a>. Dzisiaj jesteśmy już po drugiej edycji każdej z imprez. Na obu &ndash; <a href="http://www.facebook.com/groups/meetjs.wroclaw/">Meet.JS Wrocław</a> i <a href="http://pl-pl.facebook.com/wroclawgtug">GTUG Wrocław</a> przedstawiałem ten sam temat &ndash; Node.JS. Na szczęście okazało się, że zbiór wspólny uczestników był bardzo mały i chyba nawet nikt nie przysnął :). Poniżej link do prezentacji.</p>
<p><a href="http://reinmar.github.com/meetjs-nodejs/"><img src="/wp-content/uploads/meetjs_nodejs.png" alt="Prezentacja o Node.JS"></a></p>
<p>Dodatkowo zapraszam (w szczególności uczestników GTUG-a, na którym było więcej kodu) do <a href="https://github.com/Reinmar/meetjs-nodejs">projektu na Githubie</a>, gdzie wgrałem źródła.</p>
<p>Na koniec chciałem jeszcze podziękować organizatorom za trud włożony w dogranie tych spotkań i Wam, uczestnikom, za przybycie i zadawanie ciekawych pytań :). Do zobaczenia na następnych imprezach.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/' rel='bookmark' title='Wrocław wita JavaScript – Meet.JS i Wrocław GTUG'>Wrocław wita JavaScript – Meet.JS i Wrocław GTUG</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/' rel='bookmark' title='Node.js i middle-end – przenośny kod i emulacja przeglądarki'>Node.js i middle-end – przenośny kod i emulacja przeglądarki</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wrocław wita JavaScript – Meet.JS i Wrocław GTUG</title>
		<link>http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/</link>
		<comments>http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 17:28:21 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[barcamp]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gtug]]></category>
		<category><![CDATA[meet.js]]></category>
		<category><![CDATA[wrocław]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1273</guid>
		<description><![CDATA[Ku mej rozpaczy, od maja tego roku, kiedy to odbyło się szkolenie z SSJS by DevMeetings, żaden JavaScriptowy event nie zawitał do Wrocławia. Co więcej &#8211; mam wrażenie, że w ogóle nie wydarzyło się nic związanego z szeroko pojętym frontendem. Na szczęście dwie niezależne ekipy postanowiły to zmienić i tak 24 i 29 listopada odbędą [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2011/10/17/walka-dart-vs-javascript-nokaut-podczas-wazenia/' rel='bookmark' title='Walka Dart vs JavaScript &ndash; nokaut podczas ważenia'>Walka Dart vs JavaScript &ndash; nokaut podczas ważenia</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Ku mej rozpaczy, od maja tego roku, kiedy to odbyło się szkolenie z <a href="http://devmeetings.pl/trainings/javascript-na-serwerze-ringojs-v8cgi-i-nodejs">SSJS by DevMeetings</a>, żaden JavaScriptowy event nie zawitał do Wrocławia. Co więcej &ndash; mam wrażenie, że w ogóle nie wydarzyło się nic związanego z szeroko pojętym frontendem. Na szczęście dwie niezależne ekipy postanowiły to zmienić i tak <strong>24 i 29 listopada odbędą się Meet.JS i Wrocław GTUG</strong>.</p>
<h2>Meet.JS</h2>
<p>Żeby się nie powtarzać, za <a href="http://ferrante.pl/frontend/javascript/dobra-informacja-dla-wroclawa-meet-js-wroclaw-24-11/">Damianem Wielgosikiem</a>:</p>
<blockquote><p><a href="http://meetjs.pl">Meet.js</a> jako społeczna i darmowa platforma dzielenia się wiedzą o technologiach front-endowych rozwija się w niesamowitym tempie. Dzięki chłopakom z firmy <a href="http://monterail.com">Monterail.com</a> spotkania meet.js będą organizowane również &#8211; obok Poznania, Warszawy i Krakowa &#8211; we Wrocławiu.</p>
<p><strong><a href="http://www.facebook.com/event.php?eid=192419417506290">Pierwszy event</a> odbędzie się w najbliższy czwartek 24.11.2011 w siedzibie <a href="http://monterail.com">Monterail</a>. Start od 18!</strong></p>
<p>Jednocześnie poszukiwani są prelegenci do tego ekscytującego wydarzenia. Jeśli chcesz podzielić się czymś o HTML5, CSS3 czy JS nie zastanawiaj się! Bartek Pietrzak, organizator meet.js, czeka na zgłoszenia wszystkich chętnych pod <a href="mailto:bartosz@monterail.com">bartosz@monterail.com</a>.</p>
</blockquote>
<p>Więcej informacji na <a href="http://www.facebook.com/event.php?eid=192419417506290">Facebooku</a>, <a href="https://twitter.com/meetjs">@meetjs</a> i u <a href="http://ferrante.pl/frontend/javascript/dobra-informacja-dla-wroclawa-meet-js-wroclaw-24-11/">Damiana</a>.</p>
<h2>Wrocław GTUG &ndash; Wrocław Google Technology User Group</h2>
<p>Z braku weny, również cytat, tym razem z <a href="http://wroclaw.gtug.pl/eventy/spotkanie1-chromeapps">oficjalnej strony wydarzenia</a>:</p>
<blockquote><p>Zapraszamy serdecznie na pierwsze spotkanie wrocławskiej grupy GTUG.</p>
<p>Zaczniemy krótkim wprowadzeniem na temat działalności naszej grupy. Jednakże tematem wiodącym spotkania będą aplikacje dla platformy Chrome. Poruszone zostaną zagadnienia związane z możliwościami jakie daje ta platforma. Postaramy się zaprezentować przykładowe aplikacje oraz technologie wykorzystane do ich stworzenia.</p>
<p>Na koniec przedstawimy pomysły na kolejne eventy i ewentualne tematy kolejnych spotkań.
<p><strong>Po spotkaniu proponujemy wspólne wyjście na piwo :)</strong></p>
</blockquote>
<p>Spotkanie odbędzie się we <strong><a href="http://mapy.google.pl/maps?q=Google+Wroclaw,+Wroclaw&#038;hl=pl&#038;ll=51.117607,17.042401&#038;spn=0.001658,0.004128&#038;sll=51.097846,17.053824&#038;sspn=0.013273,0.033023&#038;vpsrc=6&#038;t=w&#038;hq=Google+Wroclaw,+Wroclaw&#038;z=19&#038;iwloc=A">wrocławskim biurze Google (Bema Plaza)</a> we wtorek, 29 listopada, o godzinie 19:00</strong>. Możliwe są jeszcze drobne korekty dotyczące miejsca i na pewno pojawi się formularz rejestracyjny. Tak więc polecam śledzić WroGTUG-a, do wyboru &ndash; <a href="http://www.facebook.com/wroclawgtug">Facebook</a>, <a href="https://plus.google.com/114034723187684195194/posts">Google+</a>, <a href="https://twitter.com/wroclawgtug">@wroclawgtug</a>.</p>
<h2>Do zobaczenia!</h2>
<p>Ja okazji nie przegapię i jeśli studia nie przeszkodzą, to pojawię się na obu spotkaniach. Sam niestety, ze względu na napięty czas przed obroną pracy inżynierskiej, nic nie powiem, ale prelegentów nigdy dość, więc chętni niech się zgłaszają :).</p>
<p>Przy okazji dowiedziałem się, że nie tylko ja uważam, że we Wrocławiu firm zajmujących się frontendem na poziomie praktycznie nie ma. Mamy setki korporacyjnych miejsc pracy dla programistów Javy i C#, ale związanych z webem prawie nie widać. Najgorzej wypada JavaScript, w związku z czym swój wzrok musiałem skierować na Poznań, Kraków, czy Warszawę. Trochę szkoda będzie wyjeżdżać :).</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2011/10/17/walka-dart-vs-javascript-nokaut-podczas-wazenia/' rel='bookmark' title='Walka Dart vs JavaScript &ndash; nokaut podczas ważenia'>Walka Dart vs JavaScript &ndash; nokaut podczas ważenia</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Walka Dart vs JavaScript &#8211; nokaut podczas ważenia</title>
		<link>http://code42.pl/2011/10/17/walka-dart-vs-javascript-nokaut-podczas-wazenia/</link>
		<comments>http://code42.pl/2011/10/17/walka-dart-vs-javascript-nokaut-podczas-wazenia/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 22:47:04 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[harmony]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1260</guid>
		<description><![CDATA[Myślałem, że nie napiszę nic o Darcie, bo cała historia z nim związana z początku nie wywoływała we mnie żadnych specjalnie negatywnych czy pozytywnych emocji. Dzięki Zbyszkowi Branieckiemu i Markowi Stępniowi trochę szerzej spojrzałem na temat, biorąc pod uwagę też historie o których, czy to z racji mojego krótkiego życia, czy braku wiedzy o pracach [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/' rel='bookmark' title='Wrocław wita JavaScript – Meet.JS i Wrocław GTUG'>Wrocław wita JavaScript – Meet.JS i Wrocław GTUG</a></li>
<li><a href='http://code42.pl/2010/12/22/zarezerwowane-slowa-kluczowe-w-javascript-gramatyka-jezyka/' rel='bookmark' title='Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka'>Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Myślałem, że nie napiszę nic o Darcie, bo cała historia z nim związana z początku nie wywoływała we mnie żadnych specjalnie negatywnych czy pozytywnych emocji. Dzięki <a href="http://diary.braniecki.net/">Zbyszkowi Branieckiemu</a> i <a href="http://blog.marcoos.com/">Markowi Stępniowi</a> trochę szerzej spojrzałem na temat, biorąc pod uwagę też historie o których, czy to z racji mojego krótkiego życia, czy braku wiedzy o pracach komitetów i producentów przeglądarek, nie wiedziałem i&#8230; sami przeczytajcie. Załączam poniżej coś co miało stać się przydługim komentarzem na <a href="http://www.goldenline.pl/forum/2621108/czy-dart-to-nastepca-javascriptu-od-google">forum Goldenline</a>.</p>
<h2>Pożal się Google</h2>
<p>To co zrobiło Google, to żart. Cała historia z wewnętrznymi, nie do końca miłymi mailami z Google&#8217;a, które wyszły na światło dzienne, sam Dart i otoczka PR-owa jaką ma, to jedno wielkie nieporozumienie. Google się nie popisało i, moim skronym zdaniem, wyjdzie to tylko na dobre open webowi.</p>
<p>Wyobraźmy sobie, co by się stało gdyby Dart rzeczywiście powalał na kolana i miałby świetnie zaimplementowaną, super wydajną i dostępną out of the box w Chrome maszynę. Szybko znalazłoby się grono fan boy&#8217;ów, którzy bez zastanowienia zaczęliby pisać aplikacje &#8222;only for Chrome&#8221;, bądź &#8222;works best with Chrome&#8221;, z ewentualną, wątpliwej jakości, kompilacją do powolnego i starego JavaScriptu dla &#8222;gorszych przeglądarek&#8221;. (BTW. <a href="https://gist.github.com/1277224">hello world w Dartcie</a> skompilowany do JS to 17<strong>000</strong> linii kodu :D).</p>
<p><span id="more-1260"></span></p>
<p>Po chwili okazałoby się, że Google, wykorzystując swoją pozycję lidera na wielu rynkach, zaczyna (pośrednio &ndash; przez zadowolonych użytkowników) wymuszać na innych producentach implementację Darta. No dobra &ndash; wygrał, ale w czym problem, pytacie? W tym, że Google nie raczy podzielić się odpowiedniej jakości specyfikacją języka i Mozilla, MS, czy Opera zostają zmuszone do reverse engineeringu z Chrome&#8217;a. Brzmi jak głupia apokaliptyczna wizja? Problem w tym, że ten przypadek już mieliśmy z protokołem SPDY, ponieważ Mozilla została zmuszona przez Google do zgadywania jak on w szczegółach działa. Koniec końców, po wykonaniu nieprzyjemnej pracy, pozostali producenci i tak kończą z &#8222;gorszą&#8221; implementacją. Innymi słowy &ndash; wracamy do czasów wojny przeglądarek i nieczystych zagrań. W dodatku pieczę nad specyfikacją języka sprawuje Google i wcale nie mamy pewności, czy się nią podzieli.</p>
<p>Dalej brzmi to jak bajka? Ciekawostka &ndash; opublikowana &#8222;specyfikacja&#8221; (wczesny draft oczywiście) Darta ma 70 stron, a specyfikacja wiele razy mniej złożonego ES5 250 stron. I nie, nie z powodu wielkości fonta. Mówicie &ndash; są języki, które radzą sobie bez specyfikacji &ndash; Python, Ruby &ndash; i są świetne (ktoś wymienił PHP &ndash; strzał w stopę w tej dyskusji :D). Tak, ale implementuje je jeden producent. W webie to nie działa i nigdy nie działało. Chcecie żeby przeglądarki miały spójne implementacje, to nie cofajcie się teraz o krok wstecz (prawie jak cofać się do tyłu :P). Nie po to wielokrotnie straciliśmy włosy na głowie (a i twarz też, bo czasami głupio się przyznać &ndash; &#8222;jestem programistą JavaScript&#8221;), by zapominać czego nauczyła nas historia. Nie po to został włożony i nadal jest wkładany ogromny trud w to, by ujednolicić i dogłębnie dospecyfikować wykorzystywane przez nas technologie, byśmy teraz tę pracę skreślili i zaczęli od początku. W szczególności, że&#8230;<br />
<h2>Na poważnie, czyli z forkowaniem za pan brat</h2>
<p>&#8230; nie ma takiej potrzeby. Wiele osób, w tym i ja, narzeka na JavaScript. Niektórzy wciąż nie wiedzą ile naprawił ES5 ze strict modem, niektórzy też nie zdają sobie sprawy ile jeszcze problemów jest do rozwiązania. Większość jednak narzeka i moim zdaniem słusznie. Na szczęście trwają prace nad ES6 aka Harmony aka ES.next (w których oczywiście Google uczestniczy). O ile, co smutne, ale racjonalne, ES5 nie wprowadził żadnych (może poza strict modem) przełomowych zmian w JavaScriptcie, o tyle ES6 takie zmiany ma wprowadzić, włącznie z dużymi w składni (choć Marcoos mi ostatnio powiedział, że myślą o wydaniu pośrednim, bez zmian składniowych, stąd pośrednie nazwy &ndash; oby pomysł upadł &ndash; miejcie jaja, Panowie!).</p>
<p>Na pewno jednak ten właściwy ES6 zrywa ze wsteczną zgodnością. Jest więc pole do popisu i czas, by, jeśli ktoś się postara, niemal od nowa projektować pewne aspekty języka. Można mieć tylko jeden zarzut do Harmony &ndash; nic nie wiemy o planowanym terminie zakończenia prac. Jednym z argumentów zwolenników strategii Google jest to, że &#8222;nie chcieli czekać, aż się powolny komitet naprodukuje i jako największy gracz wzięli sprawy w swoje ręce&#8221;. Brzmi niemal przekonująco. Poza tym, że Darta też szybko w wersji stabilnej i szeroko dostępnej nie zobaczymy (jeśli w ogóle). W dodatku praktyka odległej wersji finalnych HTML5 i CSS3 pokazuje, że dzięki wczesnym prototypom częściowym możemy raz, że wiele poprawić jeszcze podczas prac nad specyfikacją, dwa że płynnie przejść pomiędzy wersjami i szybko z nowych ficzerów korzystać. Co prawda JavaScript, to nie CSS, gdzie możemy sobie pozwolić na graceful degradation, jednak gracze typu Google bez problemu mogą serwować inne źródła w zależności od zdolności przeglądarki (a i tak mówimy o kompilacji ES6 do ES3, bo polyfilli to nie będzie). W dodatku wiele osób pisze aplikacje w JavaScript na w miarę przewidywalne środowiska (intranet, komórki, serwer), gdzie problemu nie ma w ogóle.</p>
<p>Stąd przechodzę do pytania &ndash; dlaczego Google zamiast forkować istniejące rozwiązania, nie zdecydowało się na wczesną, testową implementację ES6 w V8 (choć zdaje się chodziły takie słuchy)? Dzięki temu mogłoby wpływać na prace komitetu (wprowadzać ficzery w V8 i pokazywać, że świetnie się przyjmują wśród developerów, bądź po prostu dobrze działają), przyspieszyć je i poprawić zawczasu wiele wątpliwych kwestii. Spotkałem się też z argumentem, że konkurencja jest przecież dobra. Owszem, mamy na szczęście kilku producentów i stosunkowo równomierny ich udział w rynku. Moim zdaniem to wystarcza, co widać choćby na przykładzie wcześniej przeze mnie wspomnianych HTML5 i CSS3 (kontrargument swoją drogą, to to, że wyścig rodzi kiepskie implementacje &ndash; vide koszmarne formsy).</p>
<p>Bawi mnie niezmiernie jeszcze jedna kwestia. Dart wcale nie jest fajny. Wygląda jak Java, jest toporny, nie ściągnie gawiedzi jak laska z cycem na wierzchu zwana CoffeeSkryptą (BTW. uroda z inteligencją w parze nie idzie &ndash; to może ten Dart taki zły nie jest? Małżeństwo z rozsądku? ;). Nie jest też wybitnie rewolucyjny, ani&#8230; odległy od ES6. Koncepcje, które znalazłem w Dartcie widywałem też w materiałach o ES6. Jego implementacja też póki co nie powala na ziemię pod względem wydajności, a był to przecież podobno jeden z powodów porzucenia JS. W dodatku pokazuje to jak wiele pracy jest do wykonania, by dogonić już wiele lat rozwijany engine V8. To jest kolejny powód dla którego nie rozumiem decyzji Google&#8217;a.</p>
<h2>Jest też plus</h2>
<p>Jest jednak jedna rzecz, która mi się podoba w Dartcie &ndash; szersza biblioteka standardowa (włączając w to sensowną implementację DOM-a). Uważam, że w tej chwili jednym z największych problemów JavaScriptu, jest brak ustandaryzowanych (mniej, lub bardziej formalnie) podstawowych narzędzi. Ja np. w najświeższym projekcie postanowiłem wykorzystać <a href="https://github.com/medikoo/deferred">deferred</a> i <a href="https://github.com/medikoo/es5-ext">es5-ext</a> skompilowane do niecommonjsowej postaci. Zastanawiałem się jednak, czy nie wolę underscore&#8217;a. Ale zaraz &ndash; deferred i tak korzysta z es5-ext, więc ten kod i tak załaduję (tutaj ukłon w kierunku Medikoo &ndash; na szczęscie es5-ext jest 100% zmodularyzowane, więc konfigurowalne). Potrzebowałem jeszcze czegoś do DOM-a. Z jQuery nie skorzystam, bo nie potrzebuję 90% (dosłownie!) tej biblioteki, w dodatku pokrywa mi się z deferred i trochę es5-ext, no i szukałem czegoś lekkiego. Trafiłem na xui.js, które okazało się niedopieszczone. Szukałem czegoś do single page apps &ndash; Backbone? Nieee&#8230; ktoś wymyślił, że dla XHR-a,  delegate&#8217;a i deferred (i czegoś jeszcze?) skorzysta z jQuery. Jeszcze gorzej chyba ze Spine.js, gdzie znalazłem jakoś z 5 odniesień do jQuery, ale zaszytych głęboko w kodzie, bez możliwości łatwej podmiany. Przy całym tym śmietniku idiotycznych decyzji twórców tych (i wielu innych) narzędzi, są myślące osobniki, które wyprodukowały takie mini biblioteki jak <a href="http://millermedeiros.github.com/crossroads.js/">Crossroads</a>, czy <a href="http://millermedeiros.github.com/js-signals/">js-signals</a>. Robiące dokładnie jedną rzecz i nie zawierające zbędnych zależności.</p>
<p>Żalę się generalnie, ale nie bez powodu. Dart rozwiązałby połowę moich problemów. Mamy i promise&#8217;y, i wygodniejszego DOM-a. Dużo więcej ciekawych rzeczy niestety nie znalazłem, ale początek jest dobry. Uważam, że to jest aspekt języka, na który powinny zwrócić uwagę osoby pracujące nad ES6. Wiem na pewno, że jeden problem zostanie rozwiązany &ndash; zostaną wprowadzone natywne moduły. Trochę martwi mnie ich rozbieżność w stosunku do CommonJS-owej wersji (i trochę niezrozumiała dla mnie decyzja o wprowadzeniu nowej składni), ale może uda się to zgrabnie rozegrać.</p>
<h2>Podsumowując</h2>
<p>Nie wierzę, a przynajmniej nie chcę wierzyć, w sukces Darta. Póki co niczym mnie nie zainteresował i nie zamierzam się w niego zagłębiać. Mam nadzieję, że byłaby to strata czasu.</p>
<p>Zauważyliście pewnie, że brakuje w treści linków do źródeł. Tak &ndash; nie chce mi się. Google w tym wypadku pomoże :). Poza tym, nie chcę być wyrocznią, nie chcę napisać pracy doktorskiej, nie chcę nikogo zniszczyć, wypunktowując go bezlitośnie. Co więcej, możliwe, że sam niedługo zmienię na co poniektóre tematy zdanie, bo i nie mam pełnej wiedzy o tym co się dzieje i co się stanie. Powyższa opinia rodziła się we mnie jednak już kilka tygodni, więc nie jest też pisana pod wpływem wielkich emocji. Może więc jest racjonalna :).</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/11/17/wroclaw-wita-javascript-meet-js-i-wroclaw-gtug/' rel='bookmark' title='Wrocław wita JavaScript – Meet.JS i Wrocław GTUG'>Wrocław wita JavaScript – Meet.JS i Wrocław GTUG</a></li>
<li><a href='http://code42.pl/2010/12/22/zarezerwowane-slowa-kluczowe-w-javascript-gramatyka-jezyka/' rel='bookmark' title='Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka'>Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/10/17/walka-dart-vs-javascript-nokaut-podczas-wazenia/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Moje prezentacje z DevMeetings i MeetJS</title>
		<link>http://code42.pl/2011/10/09/moje-prezentacje-z-devmeetings-i-meetjs/</link>
		<comments>http://code42.pl/2011/10/09/moje-prezentacje-z-devmeetings-i-meetjs/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 13:59:58 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[HTML + CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[deferred]]></category>
		<category><![CDATA[devmeetings]]></category>
		<category><![CDATA[middle-end]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[promise]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1255</guid>
		<description><![CDATA[Trzy tygodnie temu zapraszałem Was na warsztaty DevMeetings z middle-endu, które prowadziłem. Dodatkowo, czego jeszcze wtedy nie wiedziałem, zostałem zaproszony jako speaker na MeetJS do Krakowa, gdzie zdecydowałem się opowiedzieć o jednym wątku z DevMeetingu &#8211; asynchronicznej pułapce. Poniżej zamieszczam linki do tych prezentacji. Podobne wpisy:Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław Darmowe [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
<li><a href='http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/' rel='bookmark' title='Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS'>Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Trzy tygodnie temu <a href="http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/">zapraszałem Was</a> na <a href="http://devmeetings.pl/trainings/middle-end-w-oparciu-o-serverside-js">warsztaty DevMeetings z middle-endu</a>, które prowadziłem. Dodatkowo, czego jeszcze wtedy nie wiedziałem, zostałem zaproszony jako speaker na <a href="http://meetjs.pl">MeetJS</a> do Krakowa, gdzie zdecydowałem się opowiedzieć o jednym wątku z DevMeetingu &ndash; asynchronicznej pułapce. Poniżej zamieszczam linki do tych prezentacji.</p>
<p><a href="http://reinmar.github.com/dm-middle-end/pres/"><img src="http://code42.pl/wp-content/uploads/middleend.png" alt="Middle-end w oparciu o NodeJS @ DevMeetings by Piotrek Koszuliński"></p>
<p><a href="http://reinmar.github.com/meetjs-async/"><img src="http://code42.pl/wp-content/uploads/asynchroniczna_pulapka.png" alt="Asynchroniczna pułapka @ MeetJS by Piotrek Koszuliński"></p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
<li><a href='http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/' rel='bookmark' title='Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS'>Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/10/09/moje-prezentacje-z-devmeetings-i-meetjs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zapraszam na darmowe szkolenie DevMeeting &#8211; middle-end w oparciu o NodeJS</title>
		<link>http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/</link>
		<comments>http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 12:16:31 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[devmeetings]]></category>
		<category><![CDATA[middle-end]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1191</guid>
		<description><![CDATA[Prawie miesiąc temu zapraszałem Was na różne wydarzenia związane z JavaScriptem, które miały odbyć się tej jesieni. W dwóch z nich miałem brać udział jako uczestnik &#8211; to jest na DevMeetingach w Poznaniu i Krakowie. Poznań mamy już za sobą, a w Krakowie nastąpi mała zmiana &#8211; zamiast uczestnikiem, będę prowadzącym. Ekipa organizująca szkolenia zwróciła [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
<li><a href='http://code42.pl/2011/10/09/moje-prezentacje-z-devmeetings-i-meetjs/' rel='bookmark' title='Moje prezentacje z DevMeetings i MeetJS'>Moje prezentacje z DevMeetings i MeetJS</a></li>
<li><a href='http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/' rel='bookmark' title='Node.js i middle-end – przenośny kod i emulacja przeglądarki'>Node.js i middle-end – przenośny kod i emulacja przeglądarki</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Prawie miesiąc temu <a href="http://code42.pl/2011/08/29/javascript-na-jesien-2011/">zapraszałem Was</a> na różne wydarzenia związane z JavaScriptem, które miały odbyć się tej jesieni. W dwóch z nich miałem brać udział jako uczestnik &ndash; to jest na DevMeetingach w <a href="http://devmeetings.pl/trainings/wydajno%C5%9B%C4%87-nodejs-kontra-reszta-%C5%9Bwiata">Poznaniu</a> i <a href="http://devmeetings.pl/trainings/middle-end-w-oparciu-o-serverside-js">Krakowie</a>. Poznań mamy już za sobą, a w Krakowie nastąpi mała zmiana &ndash; <strong>zamiast uczestnikiem, będę prowadzącym</strong>.</p>
<p>Ekipa organizująca szkolenia zwróciła się do mnie z prośbą, bym zastąpił Davida, któremu wypadły pilne sprawy. Nie mogłem odmówić i zabrałem się za przygotowania. Czego możecie się spodziewać? Na pewno szkolenie będzie kręciło się w okół <strong>Node&#8217;a i middle-endu</strong>. W związku z obserwacjami dotyczącymi problemów, jakie z SSJS mieli uczestnicy <a href="http://devmeetings.pl/trainings/bazy-nosqlowe-naturalny-storage-aplikacji-jsowych">warszawskiego meetingu</a>, postaram się wyjaśnić, jak organizować kod, radzić sobie z asynchronicznością, czy pisać przenośne moduły w standardzie CommonJS. Poruszę więc kwestię <strong>odmiennych charakterystyk przeglądarkowego i serwerowego JavaScriptu</strong>. Wstęp ten przyda się do zadań praktycznych, które tak jak na pozostałych jesiennych meetingach będą kluczowym elementem Krakowskiego szkolenia.</p>
<p><strong><a href="http://devmeetings.pl/trainings/middle-end-w-oparciu-o-serverside-js#registration_form">Rejestracja</a></strong> jest <strong>darmowa</strong> i jeszcze <strong>otwarta</strong>. Do zobaczenia w Krakowie :)</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
<li><a href='http://code42.pl/2011/10/09/moje-prezentacje-z-devmeetings-i-meetjs/' rel='bookmark' title='Moje prezentacje z DevMeetings i MeetJS'>Moje prezentacje z DevMeetings i MeetJS</a></li>
<li><a href='http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/' rel='bookmark' title='Node.js i middle-end – przenośny kod i emulacja przeglądarki'>Node.js i middle-end – przenośny kod i emulacja przeglądarki</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JavaScript na jesień 2011</title>
		<link>http://code42.pl/2011/08/29/javascript-na-jesien-2011/</link>
		<comments>http://code42.pl/2011/08/29/javascript-na-jesien-2011/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 14:59:52 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[HTML + CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[chouchdb]]></category>
		<category><![CDATA[devmeetings]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[konferencja]]></category>
		<category><![CDATA[middle-end]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[ssjs]]></category>
		<category><![CDATA[wydajność]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1168</guid>
		<description><![CDATA[Nieubłaganie zbliżamy się do końca lata, a na pewno letniej pogody. Warto więc zaplanować sobie kilka indoorowych imprez. Oto moje propozycje: DevMeetings &#8211; hot topics Na początku lata ekipa z DevMeetings zorganizowała trzydniowy DevCamp, na którym wykrystalizowały się trzy ciekawe backendowe tematy. Teraz nadszedł czas, aby przyjrzeć im się dokładniej. I tak odbędą się po [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/05/08/falsy-values-2011-prawdziwy-javascriptowy-event/' rel='bookmark' title='Falsy Values 2011 &#8211; prawdziwy JavaScriptowy event'>Falsy Values 2011 &#8211; prawdziwy JavaScriptowy event</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Nieubłaganie zbliżamy się do końca lata, a na pewno letniej pogody. Warto więc zaplanować sobie kilka indoorowych imprez. Oto moje propozycje:</p>
<h2><a href="http://devmeetings.pl">DevMeetings &ndash; hot topics</a></h2>
<p><img alt="DevMeetings - hot topics" src="http://code42.pl/wp-content/uploads/dm_logos.png" width="536" height="124"/></p>
<p>Na początku lata ekipa z DevMeetings zorganizowała trzydniowy <a href="http://devcamps.pl">DevCamp</a>, na którym wykrystalizowały się trzy ciekawe backendowe tematy. Teraz nadszedł czas, aby przyjrzeć im się dokładniej. I tak odbędą się po kolei:</p>
<p><span id="more-1168"></span></p>
<ul>
<li><strong><a href="http://devmeetings.pl/trainings/wydajno%C5%9B%C4%87-nodejs-kontra-reszta-%C5%9Bwiata">Wydajność Node.JS kontra reszta świata</a></strong> (3 września, Poznań) &ndash; kontrowersyjny temat &ndash; ile prawdy jest we wszystkich stwierdzeniach o super wydajności Node&#8217;a? Trochę na ten temat dowiedzieliśmy się już na <a href="http://devcamps.pl/">DevCampie</a> (polecam zajrzeć do materiałów z naszych badań), jednak wiele osób krytykowało zastosowane podejście jako zbyt oderwane od rzeczywistości. Dlatego tym razem postaramy przygotować się prawdziwą aplikację i na tej podstawie wyciągnąć wnioski. Rozpoczęła się już <a href="http://devmeetings.pl/trainings/wydajno%C5%9B%C4%87-nodejs-kontra-reszta-%C5%9Bwiata#forum">dyskusja</a>, o tym jak podejść do tematu. <strong>Ja oczywiście będę</strong>, a Ty wciąż możesz się <strong><a href="http://devmeetings.pl/trainings/wydajno%C5%9B%C4%87-nodejs-kontra-reszta-%C5%9Bwiata#registration_form">zarejestrować</a></strong>.</li>
<li><strong><a href="http://devmeetings.pl/trainings/bazy-nosqlowe-naturalny-storage-aplikacji-jsowych">Bazy noSQL-owe &ndash; naturalny storage aplikacji JSON-owych</a></strong> (10 września, Warszawa) &ndash; drugi temat na czasie, czyli bazy noSQL-owe (np. CouchDB, MongoDB, Redis). Meeting powinien być interesujący dla zwolenników, jak i przeciwników tego typu rozwiązań, w końcu nie ma nic lepszego niż potężny flame :). Jedni i drudzy dodatkowo dowiedzą się jak radzić sobie w nowym środowisku, które wymaga nowego podejścia (żegnaj <code>SELECT</code>, witaj <code>map-reduce</code>). Tym razem mnie nie będzie, bo do Warszawy mi zbyt daleko, ale i tak polecam :). Również można się jeszcze <strong><a href="http://devmeetings.pl/trainings/bazy-nosqlowe-naturalny-storage-aplikacji-jsowych#registration_form">zarejestrować</a></strong>.</li>
<li><strong><a href="http://devmeetings.pl/trainings/middle-end-w-oparciu-o-serverside-js">Middle-end w oparciu o serverside JavaScript</a></strong> (24 września, Kraków) &ndash; to temat, na który czekam z niecierpliwością. Z jednej strony bowiem wiem co to middle-end, o którym nawet <a href="http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/">pisałem</a>, a na <a href="http://devcamps.pl/topics/int_middle_end">DevCampie</a> bawiliśmy się w jego implementacje, z drugiej, faktyczna architektura całego przekroju zastosowań (nie tylko DOM po stronie serwera, ale też np. walidatory) jest dla mnie pewną zagadką. Polecam ten temat wszystkim, którzy zastanawiali się kiedyś tym, czy da się współdzielić kod pomiędzy serwerem i przeglądarką i jak do tego podejść. <strong>Ja oczywiście będę</strong> i zachęcam do <strong><a href="http://devmeetings.pl/trainings/middle-end-w-oparciu-o-serverside-js#registration_form">rejestrowania się</a></strong>.</li>
</ul>
<h2><a href="http://ongamestart.com/">onGameStart &ndash; first HTML5 conference</a></h2>
<p><img alt="onGameStart" src="http://code42.pl/wp-content/uploads/ogs.png" width="200" height="131" class="alignleft"/></p>
<p>Konferencja organizowana przez <a href="http://michalbe.blogspot.com/">Michała Budzyńskiego</a> odbędzie się <strong>22-23 września w Warszawie</strong>. Michałowi udało się ściągnąć wielu ciekawych prelegentów, więc na pewno warto posłuchać co mają do powiedzenia. W szczególności, że temat gier budowanych przy użyciu pakietu HTML5+CSS3+JS, jest ostatnimi czasy bardzo na topie i dużo w tej kwestii się dzieje. Mnie niestety nie będzie, mimo że <a href="http://ferrante.pl/frontend/javascript/ostateczna-lista-zwyciezcow-konkursu-na-najkrotszy-skrypt/">wygrałem bilet</a>, ale polecam zainteresowanym. Bilety po 79 i 89 euro są jeszcze <a href="http://www.amiando.com/onGameStart2011.html">do kupienia</a>. Można też spróbować <strong>wygrać bilet</strong> u <a href="http://blog.ily.li/2011/08/porcine-css3html5-contest/">Lidii Wilczyńskiej</a>.</p>
<h2><a href="http://frontrowconf.com/">Front Row Conference</a></h2>
<p><img alt="Front Row Conference" src="http://code42.pl/wp-content/uploads/fr.png" width="100" height="128" class="alignleft"/></p>
<p>Konferencja poświęcona frontendowi, która odbędzie się <strong>20-21 października w Krakowie</strong>. Póki co nie ogłoszono zbyt wielu prelegentów, ale dwóch może być Wam znanych. To wspomniany przeze mnie przed chwilą <a href="http://twitter.com/michalbe">Michał Budzyński</a> oraz znany uczestnikom DevMeetingów <a href="http://twitter.com/m4r00p">Marek Pawłowski</a>. Bilety <a href="http://frontrowconf.com/registration/">do kupienia</a> po 123 euro. Na razie, przyznam szczerze, odnoszę wrażenie, że organizatorom idzie topornie z organizacją, ale kibicuję im, bo im więcej tego typu imprez w Polsce, tym lepiej.</p>
<p><strong>Do zobaczenia we wrześniu i październiku!</strong></p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/05/08/falsy-values-2011-prawdziwy-javascriptowy-event/' rel='bookmark' title='Falsy Values 2011 &#8211; prawdziwy JavaScriptowy event'>Falsy Values 2011 &#8211; prawdziwy JavaScriptowy event</a></li>
<li><a href='http://code42.pl/2011/02/08/meet-js-javascriptowe-spotkanie-w-realu/' rel='bookmark' title='meet.js &#8211; JavaScriptowe spotkanie w realu'>meet.js &#8211; JavaScriptowe spotkanie w realu</a></li>
<li><a href='http://code42.pl/2010/12/31/darmowe-szkolenie-z-programowania-gier-w-javascript-by-devmeetings/' rel='bookmark' title='Darmowe szkolenie z programowania gier w JavaScript by DevMeetings'>Darmowe szkolenie z programowania gier w JavaScript by DevMeetings</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/08/29/javascript-na-jesien-2011/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Co lepiej wiedzieć o JavaScriptcie cz.2.: hoisting, deklaracje funkcji i wyrażenia funkcyjne</title>
		<link>http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/</link>
		<comments>http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/#comments</comments>
		<pubDate>Sat, 20 Aug 2011 20:33:00 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[deklaracje funkcji]]></category>
		<category><![CDATA[fd]]></category>
		<category><![CDATA[fe]]></category>
		<category><![CDATA[funkcje]]></category>
		<category><![CDATA[hoisting]]></category>
		<category><![CDATA[nfe]]></category>
		<category><![CDATA[wyrażenia funkcyjne]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1097</guid>
		<description><![CDATA[W poprzednim artykule pokazałem czym się różni zasięg blokowy od funkcyjnego, jakie problemy może spowodować ten drugi i jakie są plany na przyszłość. Wspomniałem też o zasięgu statycznym, czyli o domknięciach. W tym artykule chciałbym wyjaśnić czym jest hoisting i porównać deklaracje funkcji (function declarations) z wyrażeniami funkcyjnymi (function expressions). Zauważyłem, że są to tematy [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/' rel='bookmark' title='Co lepiej wiedzieć o JavaScriptcie cz.1.: typy zasięgu i domknięcia'>Co lepiej wiedzieć o JavaScriptcie cz.1.: typy zasięgu i domknięcia</a></li>
<li><a href='http://code42.pl/2011/09/24/php-statyczne-zmienne-funkcji-%e2%80%94-do-czego-moga-sie-przydac/' rel='bookmark' title='PHP: Statyczne zmienne funkcji — do czego mogą się przydać?'>PHP: Statyczne zmienne funkcji — do czego mogą się przydać?</a></li>
<li><a href='http://code42.pl/2011/04/10/najszybszy-stworek-algorytm-genetyczny-w-javascriptcie/' rel='bookmark' title='Najszybszy stworek &ndash; algorytm genetyczny w JavaScriptcie'>Najszybszy stworek &ndash; algorytm genetyczny w JavaScriptcie</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>W <a href="http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/">poprzednim artykule</a> pokazałem czym się różni zasięg blokowy od funkcyjnego, jakie problemy może spowodować ten drugi i jakie są plany na przyszłość. Wspomniałem też o zasięgu statycznym, czyli o domknięciach.</p>
<p>W tym artykule chciałbym wyjaśnić czym jest ho<u>i</u>sting i porównać deklaracje funkcji (function declarations) z wyrażeniami funkcyjnymi (function expressions). Zauważyłem, że są to tematy obce wielu programistom JavaScript i myślę, że o ile test z poprzedniego artykułu wielu z Was nie powinien sprawić problemu, o tyle poniższy ma szansę być małym zaskoczeniem. Taką mam przynajmniej nadzieję :).</p>
<p><a href="#zrodla">Źródła</a> z których korzystałem, umieściłem na końcu wpisu.</p>
<h2>Sprawdź się!</h2>
<p>Spróbuj rozpoznać co wydrukuje każde wywołanie <code>console.log</code>. Skrypt z wszystkimi pytaniami, <strong>wraz z odpowiedziami</strong> wrzuciłem na <a href="https://gist.github.com/1159049">Gista</a>.</p>
<p><span id="more-1097"></span></p>
<h3>Hoisting</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.1:'</span><span style="color: #339933;">,</span> a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.2:'</span><span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.3:'</span><span style="color: #339933;">,</span> c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.4:'</span><span style="color: #339933;">,</span> c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>d <span style="color: #339933;">===</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.5:'</span><span style="color: #339933;">,</span> d<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Funkcje</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.1:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> a<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.2:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> b<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.3: 1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> b<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.4: 2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
b<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> c1 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> c2<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> c1<span style="color: #339933;">,</span> c2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
c1<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.5:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
c2<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.6:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Hoisting, czyli wynoszenie</h2>
<p>Myślę, że nikomu nie powinien sprawić problemów przykład <code>3.1</code>. To będzie oczywiście <code>RerefenceError</code>. Co jednak dostaniemy dla przykładu <code>3.2</code>? Deklaracja zmiennej <code>b</code> znajduje się w kodzie poniżej próby jej użycia, a więc też błąd? Nie &ndash; dostaniemy wartość <code>undefined</code>.</p>
<p>Zachowanie to jest efektem hoistingu (po polsku &ndash; wynoszenie). Polskie tłumaczenie co prawda lepiej informuje nas o wyniku działania tej konstrukcji, jednak brzmi strasznie, tak więc będę go unikał (przynajmniej w rzeczowniku :).</p>
<p>Czym jest więc hoisting? Jest to <strong>wyniesienie deklaracji zmiennych, bądź funkcji</strong> do samego początku kontekstu deklaracji (najczęściej ciała funkcji &ndash; zasięg funkcyjny), przy jednoczesnym <strong>pozostawieniu inicjalizacji samej zmiennej w oryginalnym miejscu</strong>. Takie zachowanie jest spowodowane istnieniem dwóch etapów wykonywania kodu, o czym pisze <a href="http://dmitrysoshnikov.com/notes/note-4-two-words-about-hoisting/">Dmitry Soshnikov</a>:</p>
<blockquote><p>There are two stages of the code handling: (1) entering the context, where all the data are created, and (2) the code execution stage.</p>
</blockquote>
<p>Dla przykładu przyjrzyjmy się następującej funkcji:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> fn <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> sth <span style="color: #339933;">=</span> getSomeStuff<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> sthelse <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> sthelse.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> sth <span style="color: #339933;">=</span> sthelse<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #003366; font-weight: bold;">var</span> ok <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Taka funkcja zostanie przez interpreter wykonana w następujący sposób:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> fn <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// etap 1. - deklaracje</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// zmienne automatycznie zostają</span>
    <span style="color: #006600; font-style: italic;">// zainicjalizowane wartością undefined</span>
    <span style="color: #003366; font-weight: bold;">var</span> sth<span style="color: #339933;">,</span> sthelse<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> ok<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// etap 2. - wykonanie</span>
&nbsp;
    sth <span style="color: #339933;">=</span> getSomeStuff<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    sthelse <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> sthelse.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sth <span style="color: #339933;">=</span> sthelse<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// wyjaśnienie pkt. 3.3: wszystkie deklaracje są wynoszone</span>
        <span style="color: #006600; font-style: italic;">// nawet te do których interpreter nigdy nie dojdzie</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> ok <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jak widzisz, wszystkie zmienne zadeklarowane w obrębie całego ciała funkcji zostają zgromadzone na początku. By wyeliminować &#8222;magię&#8221;, identyczny zabieg stosują ręcznie niektórzy programiści JavaScript i deklarują wszystkie zmienne na samym początku ciała funkcji (czasami wraz z inicjalizacją tych wartości, których wartość jest znana od początku). Ja też tak postępuję jeśli ciało funkcji jest na tyle długie, że mógłbym pogubić się które zmienne mam zadeklarowane, a które nie. Przykład żywcem z kodu, który pisałem wczoraj:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> txt_ratio <span style="color: #339933;">=</span> Math.<span style="color: #660066;">ceil</span><span style="color: #009900;">&#40;</span>TXT_WIDTH <span style="color: #339933;">/</span> TXT_HEIGHT<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    rows<span style="color: #339933;">,</span> cols<span style="color: #339933;">,</span>
    geometry<span style="color: #339933;">,</span>
    x<span style="color: #339933;">,</span> y<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> t<span style="color: #339933;">,</span> d<span style="color: #339933;">,</span> xi<span style="color: #339933;">,</span> yi<span style="color: #339933;">,</span> rowi<span style="color: #339933;">,</span> coli<span style="color: #339933;">;</span></pre></div></div>

<p>Jak widać, bywa tego dużo :). Tak na marginesie, o ile w ogóle dobrą praktyką jest dzielić dłuższe funkcje na kilka osobnych, o tyle w JavaScriptcie jest to jeszcze ważniejsze. Dlaczego?</p>
<h3>Wady hoistingu</h3>
<p>Daleko szukać nie trzeba, by trafić na pierwsze wady hoistingu. W szczególności początkujący programiści nie lubią magii i niejawnych zachowań czy to we frameworkach, czy w językach samych w sobie. Spójrzmy na przykład <code>3.5</code> z testu (wyciągnąłem go z <a href="http://www.slideshare.net/ferrantes/just-advanced-javascript">prezentacji</a> <a href="http://ferrante.pl">Damiana Wielgosika</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>d <span style="color: #339933;">===</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.5:'</span><span style="color: #339933;">,</span> d<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Na pierwszy rzut oka myślimy (sam przed chwilą to zrobiłem :D) &ndash; <code>d</code> jest równe <code>10</code>, więc warunek się wykona i dostaniemy wartość <code>20</code>. Nic bardziej mylnego. Powyższy kod zostanie wykonany w następujący sposób:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> d<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//undefined!</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>d <span style="color: #339933;">===</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        d <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'3.5:'</span><span style="color: #339933;">,</span> d<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Nieco inny, ale nawet łatwiejszy do doświadczenia, przykład podał <a href="http://dmitrysoshnikov.com/notes/note-4-two-words-about-hoisting/">Dmitry Soshnikov</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined ?</span>
    <span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>CoffeScript na lekarstwo?</h3>
<p>Problem ten dostrzegli autorzy <a href="http://jashkenas.github.com/coffee-script/#lexical_scope">CoffeScriptu</a> i postanowili mu zaradzić:</p>

<div class="wp_syntax"><div class="code"><pre class="coffeescript" style="font-family:monospace;">outer = 1
changeNumbers = -&gt;
  inner = -1
  outer = 10
inner = changeNumbers()</pre></div></div>

<p>Powyższy kod zostanie skompilowany do:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> changeNumbers<span style="color: #339933;">,</span> inner<span style="color: #339933;">,</span> outer<span style="color: #339933;">;</span>
outer <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
changeNumbers <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> inner<span style="color: #339933;">;</span>
  inner <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> outer <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
inner <span style="color: #339933;">=</span> changeNumbers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Widać, że zmiennych w ogóle nie trzeba deklarować, ponieważ są automatycznie deklarowane w pierwszym kontekście wystąpienia. Rozwiązuje to problem magii hoistingu, zabezpiecza nam obiekt globalny, ponieważ nie ma opcji, żeby niezadeklarowana zmienna wypłynęła do niego (w czystym JavaScriptcie sprawę załatwia <a href="http://blog.marcoos.com/2011/01/25/ecmascript-5-strict-mode-tryb-scisly/">strict mode</a> &ndash; polecam). Co jednak jeśli chcemy ograniczyć zasięg zmiennej jedynie do zagnieżdżonej funkcji? Tego chyba autorzy CoffeeScript nie przewidzieli (jeśli się mylę, poprawcie mnie) i dla mnie to duża wada. Dlatego też z tego i kilku innych powodów mówię CoffeScriptowi nie.</p>
<h3>A jakieś zalety?</h3>
<p>Przedstawiłem wady hoistingu, ale pozostało pytanie &ndash; dlaczego w ogóle został wprowadzony, skoro powoduje tyle niejasności? Pytanie jest o tyle dobre, że nie udało mi się znaleźć na nie odpowiedzi. Jedyne o czym wspomina Dmitry Soshnikov to optymalizacja. Jak pokazał jeden z poprzednich przykładów, wyniesienie deklaracji zabezpieczyło nas przed redeklarowaniem zmiennej w pętli (<code>sth</code>), czy przy wielokrotnym użyciu (np. <code>i</code>). Hoisting nie jest jednak jedynym sposobem na radzenie sobie z tymi sytuacjami, tak więc wydaje się, że jego zastosowanie można uznać za złą decyzję twórców języka.</p>
<h2>Deklaracje funkcji vs wyrażenia funkcyjne</h2>
<p>Temat hoistingu łączy się zgrabnie z tematem funkcji. Okazuje się, że mamy w JavaScriptcie dwie konstrukcje składniowe do ich definiowania. <a href="http://es5.github.com/#x13">ECMAScript5</a> specyfikuje obydwie następująco:</p>

<div class="wp_syntax"><div class="code"><pre class="syntax" style="font-family:monospace;">FunctionDeclaration :
&nbsp;
    function Identifier ( FormalParameterListopt ) { FunctionBody }
&nbsp;
FunctionExpression :
&nbsp;
    function Identifier_opt ( FormalParameterListopt ) { FunctionBody }</pre></div></div>

<p>Początkowo wydaje się, że jedyną różnicą jest opcjonalność identyfikatora funkcji. Różnica jednak wynika z możliwości umieszczenia obydwu konstrukcji w różnych kontekstach składniowych. Deklaracja funkcji znajduje się na równi z <a href="http://pl.wikipedia.org/wiki/Instrukcja_%28informatyka%29">instrukcją</a> (statement), zaś wyrażenie funkcyjne, jak sama nazwa wskazuje, jest wyrażeniem, które jest dopiero częścią instrukcji.</p>
<p>Domyślam się, że teraz wiesz, że jest jakaś różnica, ale nie wiesz dalej co z niej wynika :). W uproszczeniu można więc powiedzieć, że deklarację funkcji mamy tam gdzie funkcja nie jest wykorzystana jako wartość (jest osobną pseudo-instrukcją). Funkcja wykorzystana jako wartość (jest częścią instrukcji) jest wyrażeniem funkcyjnym. Przykłady:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// deklaracja funkcji</span>
<span style="color: #003366; font-weight: bold;">function</span> a<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// wyrażenie funkcyjne - zostało przypisane</span>
<span style="color: #006600; font-style: italic;">// więc użycie jako wartość</span>
<span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    arg<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// przekazujemy wyrażenie funkcyjne</span>
b<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Hoisting deklaracji rozwiązaniem testu</h3>
<p>Definiując hoisting wspomniałem o tym, że zachodzi on również dla deklaracji funkcji. Inaczej niż w przypadku zmiennych, w tym wypadku wynoszona jest też cała &#8222;zawartość&#8221; funkcji, nie tylko inicjalizacja zmiennej do <code>undefined</code>. Bardzo spodobał mi się przykład, mojego własnego, skromnego autorstwa, na który, co ciekawe, sam się naciąłem :).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.1:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 2</span>
<span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> a<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.2:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 1</span></pre></div></div>

<p>Na pierwszy rzut oka nie ma w tym żadnego sensu. Kiedy pomyślimy jednak jak wynoszone są deklaracje, wszystko staje się jasne:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> a<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.1:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 2</span>
&nbsp;
a <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #3366CC;">'1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
a<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.2:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 1</span></pre></div></div>

<p>Okazuje się, że hoisting deklaracji funkcji niesie ze sobą jeszcze więcej problemów, niż hoisting deklaracji zmiennych. Załóżmy, że mamy dwa pliki ze skryptami. W pierwszym deklarujemy funkcję <code>fn</code> i w drugim również deklarujemy funkcję <code>fn</code>. W środowisku deweloperskim wszystko działa jak należy, jednak kiedy połączymy oba pliki na produkcję, funkcja z drugiego pliku nadpisuje funkcję z pierwszego i teraz również kod z pierwszego pliku korzysta z drugiej funkcji. Co prawda jest to też przykład kiepskiej architektury, ale zdarzyć się może.</p>
<h3>Named Function Expressions</h3>
<p>Pisałem o tym, że wyrażenie funkcyjne ma opcjonalny identyfikator. Wyrażenia funkcyjne z podanym identyfikatorem, to po prostu nazwane wyrażenia funkcyjne, czyli NFE. Okazuje się, że są bardzo przydatną konstrukcją, ponieważ identyfikator takiej funkcji nie jest widoczny z zewnątrz, a jedynie wewnątrz niej. Przykładem jest ostatnie zadanie z testu:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> c1 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> c2<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> c1<span style="color: #339933;">,</span> c2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
c1<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.5:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; function, function</span>
c2<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'4.6:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; ReferenceError</span></pre></div></div>

<p>Pierwszy powód dlaczego NFE są przydatne, to wycofanie w strict modzie <code>arguments.callee</code>. Dzięki NFE wciąż możemy tworzyć rekurencyjne wywołania. Teraz zamiast pisać (przykład wzięty z wybitnego <a href="http://kangax.github.com/nfe/">artykułu kangaxa o NFE</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> x <span style="color: #339933;">*</span> arguments.<span style="color: #660066;">callee</span><span style="color: #009900;">&#40;</span>x <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Napiszemy:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> factorial<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> x <span style="color: #339933;">*</span> factorial<span style="color: #009900;">&#40;</span>x <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Drugi powód to debugowanie. Niestety nienazwane wyrażenia funkcyjne, są niemal anonimowe. Używając ich widzimy później call stack pełen &#8222;anonymous function, anonymous function&#8221;. I co prawda Google się chwali, że Chrome identyfikuje funkcje anonimowe (po tym do jakich zmiennych, czy właściwości są przypisywane), ale według mnie nie działa to najlepiej. W dodatku jak nazwać funkcję przekazywaną jako callback do jakiejś funkcji? No nie da się. Dlatego w ostatnim projekcie zacząłem nazywać wiele funkcji. Na przykład:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> BigInteger <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> BigInteger<span style="color: #009900;">&#40;</span>num<span style="color: #339933;">,</span> base<span style="color: #339933;">,</span> c<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//...</span>
BigInteger.<span style="color: #660066;">prototype</span>._addOffset <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> _BI_addOffset<span style="color: #009900;">&#40;</span>n<span style="color: #339933;">,</span> w<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//...</span>
BigInteger.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">abs</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> BI_abs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>Miałem nie wspominać, ale żeby nie było &ndash; Z NFE związanych jest kilka błędów. Większość dotyczy starych wersji Safari (2.x) i Firefoksa (<=3), jednak największym problemem mogą być te związane z IE (<9). Na szczęście są stosunkowo "niekrytyczne", choć jeśli zamierzasz je stosować, to polecam <a href="http://kangax.github.com/nfe">artykuł kangaxa</a>.</p>
<h2>FD vs (N)FE &ndash; wynik walki</h2>
<p>Zdecydowanie wyrażenia funkcyjne. Pomijamy część wad hoistingu, deklaracje funkcji (ponoć) nie wszędzie są dopuszczalne (aczkolwiek nie znalazłem przykładu gdzie nie są &ndash; może ktoś zna?), deklaracje funkcji to kiepska kalka z Javy oraz argument ostateczny &ndash; 90% naszego kodu to i tak będą wyrażenia funkcyjne.</p>
<h2 id="zrodla">Źródła, czyli poczytaj więcej</h2>
<ul>
<li><a href="http://dmitrysoshnikov.com/notes/note-4-two-words-about-hoisting/">Dmitry Soshnikov &ndash; Note 4. Two words about “hoisting”</a> &ndash; bardzo lubię artykuły Dmitry&#8217;a, ponieważ schodzi aż do akademickiego poziomu,</li>
<li><a href="http://www.slideshare.net/ferrantes/just-advanced-javascript">Damian Wielgosik (Ferrante) &ndash; prezentacja Just advanced JavaScript</a> &ndash; polecam całą, ale część związana z tym artykułem zaczyna się od slajdu 132.,</li>
<li><a href="http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/">Angus Croll &ndash; Function Declarations vs. Function Expressions</a> &ndash; uzupełnienie i rozjaśnienie tego o czym ja pisałem,</li>
<li><a href="http://kangax.github.com/nfe/">Juriy &#8222;kangax&#8221; Zaytsev &ndash; Named function expressions demystified</a> &ndash; niesamowicie dokładny przegląd dotyczący NFE (m.in. omówienie kilku błędów przeglądarek); tak długie, że nie przeczytałem, ale na pewno to zrobię :D.</li>
</ul>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/' rel='bookmark' title='Co lepiej wiedzieć o JavaScriptcie cz.1.: typy zasięgu i domknięcia'>Co lepiej wiedzieć o JavaScriptcie cz.1.: typy zasięgu i domknięcia</a></li>
<li><a href='http://code42.pl/2011/09/24/php-statyczne-zmienne-funkcji-%e2%80%94-do-czego-moga-sie-przydac/' rel='bookmark' title='PHP: Statyczne zmienne funkcji — do czego mogą się przydać?'>PHP: Statyczne zmienne funkcji — do czego mogą się przydać?</a></li>
<li><a href='http://code42.pl/2011/04/10/najszybszy-stworek-algorytm-genetyczny-w-javascriptcie/' rel='bookmark' title='Najszybszy stworek &ndash; algorytm genetyczny w JavaScriptcie'>Najszybszy stworek &ndash; algorytm genetyczny w JavaScriptcie</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Co lepiej wiedzieć o JavaScriptcie cz.1.: typy zasięgu i domknięcia</title>
		<link>http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/</link>
		<comments>http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 22:25:48 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[closure]]></category>
		<category><![CDATA[domknięcia]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es6]]></category>
		<category><![CDATA[harmony]]></category>
		<category><![CDATA[scope]]></category>
		<category><![CDATA[zasięg]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=907</guid>
		<description><![CDATA[Istnieją takie aspekty języka, których w wielu przypadkach wpływ na działanie kodu jest wręcz niezauważalny, a przez to ich znajomość nie jest niezbędna do napisania nawet bardziej złożonych aplikacji. Zdarzają się jednak takie sytuacje, kiedy, widząc błąd, robimy okrągłe oczy, a z naszych gardeł wydobywa się głuche WTF i, jeśli nie jesteśmy świadomi ogromu swej [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/' rel='bookmark' title='Co lepiej wiedzieć o JavaScriptcie cz.2.: hoisting, deklaracje funkcji i wyrażenia funkcyjne'>Co lepiej wiedzieć o JavaScriptcie cz.2.: hoisting, deklaracje funkcji i wyrażenia funkcyjne</a></li>
<li><a href='http://code42.pl/2009/03/18/konsola-firebuga-echowanie-javascriptu/' rel='bookmark' title='Konsola Firebuga &#8211; &#8222;echowanie&#8221; Javascriptu'>Konsola Firebuga &#8211; &#8222;echowanie&#8221; Javascriptu</a></li>
<li><a href='http://code42.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/' rel='bookmark' title='Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem'>Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Istnieją takie aspekty języka, których w wielu przypadkach wpływ na działanie kodu jest wręcz niezauważalny, a przez to ich znajomość nie jest niezbędna do napisania nawet bardziej złożonych aplikacji. Zdarzają się jednak takie sytuacje, kiedy, widząc błąd, robimy okrągłe oczy, a z naszych gardeł wydobywa się głuche <q>WTF</q> i, jeśli nie jesteśmy świadomi ogromu swej niewiedzy, pada po chwili: <q>Znalazłem błąd w silniku przeglądarki!</q>. Co gorsza, najczęściej na rozwiązanie takiego problemu potrzeba sporo czasu i nerwów.</p>
<p>Spośród <a href="http://code42.pl/2011/08/05/javascript-po-polsku/">listy tematów do opracowania</a> wybrałem pierwsze 3, które moim zdaniem zgrabnie się łączą. Są to <b>zasięg</b> (scope), <b>ho<u>i</u>sting</b> (widziałem tłumaczenie do <q>wyniesienie</q>, ale brzmi strasznie) oraz <b>deklaracje funkcji</b> (function declaration &ndash; dalej: FD) i <b>wyrażenia funkcyjne</b> (function expression &ndash; dalej: FE). Mam nadzieję, że rozjaśnienie tych tematów pozwoli zaoszczędzić komuś trochę czasu :).</p>
<p>Artykuł będzie składał się z dwóch części. Tę część poświęciłem typom zasięgu oraz domknięciom. Następna będzie dotyczyła (edit: już jest dostępna) <a href="http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/">hoistingu i funkcji</a>.</p>
<h2>Sprawdź się!</h2>
<p>Na początek niekrótki zestaw krótkich testów. Spróbuj rozpoznać co wydrukuje każdy <code>console.log</code>. Skrypt z wszystkimi pytaniami, <strong>wraz z odpowiedziami</strong> wrzuciłem na <a href="https://gist.github.com/1134905">Gista</a>.</p>
<h3>Cz.1.</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> a <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'1.1:'</span><span style="color: #339933;">,</span> a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'1.2:'</span><span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> c_fn <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> c <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
c_fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'1.3:'</span><span style="color: #339933;">,</span> c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><span id="more-907"></span></p>
<h3>Cz.2.</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> a_fn <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> a<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.1:'</span><span style="color: #339933;">,</span> a_fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>fn<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.2:'</span><span style="color: #339933;">,</span> fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>a_fn<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>fn<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    a <span style="color: #339933;">=</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.3:'</span><span style="color: #339933;">,</span> fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>a_fn<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.4:'</span><span style="color: #339933;">,</span> a_fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    b_i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> b_i <span style="color: #339933;">&lt;</span> b.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>b_i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    b<span style="color: #009900;">&#91;</span>b_i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> b_i<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.5:'</span><span style="color: #339933;">,</span> b<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Zasięg funkcyjny i blokowy</h2>
<p>Jeśli wychowałeś się na JavaScriptcie, pierwszy test nie powinien sprawić Ci żadnego problemu. Jeśli jednak jesteś programistą Javy, bądź języka C(|++|#), to mogłeś odpowiedzieć źle. Jaka jest różnica? JavaScript jest językiem o zasięgu funkcyjnym, zaś pozostałe o zasięgu blokowym.</p>
<p>Analogiczny kod napisany w C++ (dla przykładów 1.1 i 1.2, ponieważ 1.3 jest niewykonalny) zwróciłby odpowiednio <code>1.1: 1, 1.2: error: ‘b’ was not declared in this scope</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> a <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>a<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> a<span style="color: #008080;">;</span> <span style="color: #666666;">// -&gt; 1</span>
&nbsp;
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">int</span> b <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> b<span style="color: #008080;">;</span> <span style="color: #666666;">// -&gt; błąd kompilacji</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Jak widać, blok, bądź konstrukcja <code>for</code> powodują pojawienie się nowego zasięgu. Po wykonaniu się pętli <code>a</code> wciąż jest równe <code>1</code> (<a href="http://www.java2s.com/Tutorial/Cpp/0020__Language-Basics/Variableblockscope.htm">więcej przykładów dla C++</a>). Java zachowałaby się nieco inaczej, uniemożliwiając redefiniowanie zmiennej o tej samej nazwie, jednak ogólna zasada byłaby identyczna.</p>
<p>JavaScript za to, określając sobie zasięg zmiennej, nie zwraca uwagi na żadne bloki. Jedynym ograniczeniem dla niego jest funkcja. <strong>Każda zmienna zdefiniowana w funkcji jest widoczna w tej funkcji i w funkcjach zdefiniowanych w tej funkcji, ale nigdzie poza nią</strong>. Dzięki temu otrzymamy: <code>1.1: 10, 1.2: b</code>, lecz: <code>1.3: ReferenceError</code>.</p>
<p>Zostałem kiedyś zapytany, czy istnieje możliwość podejrzenia wewnętrznego scope&#8217;a funkcji. Odpowiedź jest na szczęście przecząca (przynajmniej wedle mojego stanu wiedzy). Tak ścisłe ograniczenie zasięgu pozwala nam bezwarunkowo zabezpieczyć kod przed ingerencją z zewnątrz. Stąd na pewno gdzieś już widziałeś konstrukcję:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jest to samowykonująca się funkcja. Wszystko co zostanie zdefiniowane wewnątrz niej jest niedostępne z zewnątrz (o ile nie zostało zwrócone).</p>
<h2>Zasięg statyczny</h2>
<p>Napisałem, że zmienna zdefiniowana w funkcji jest widoczna w tej funkcji i <em>w funkcjach zdefiniowanych w tej funkcji</em>. Takie podejście nazywa się statycznym zasięgiem (druga nazwa to zasięg leksykalny &ndash; <a href="http://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_versus_dynamic_scoping">lexical scoping</a>), z tego względu, że określenie zasięgu polega jedynie na analizie statycznego kodu programu. Przeciwstawnym podejściem jest dynamiczny zasięg, a więc scope funkcji określany jest w momencie jej wywołania, a nie definicji.</p>
<p>Przyjrzyjmy się drugiemu przykładowi do tej części:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> a_fn <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> a<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>fn<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.2:'</span><span style="color: #339933;">,</span> fn<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 1</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>a_fn<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Jak widać, mimo zadeklarowania <code>var a = 2</code> w miejscu wywołania funkcji <code>a_fn()</code> zostanie zwrócone <code>1</code>. Tak więc możemy powiedzieć, że funkcja zapamiętała otoczenie swojej definicji. Zachowanie takie nazywa się domknięciem, czyli jest to sławetny postrach początkujących &ndash; <a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29">closure</a>. O domknięciach chciałbym napisać kiedyś osobny artykuł, ale dla utrwalenia jeszcze jeden przykład:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> outer <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> inner <span style="color: #339933;">=</span> outer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
inner<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 2</span></pre></div></div>

<h3>Przez referencję, głupcze!</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    b_i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> b_i <span style="color: #339933;">&lt;</span> b.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>b_i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    b<span style="color: #009900;">&#91;</span>b_i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> b_i<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'2.5:'</span><span style="color: #339933;">,</span> b<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 4</span></pre></div></div>

<p>To jest chyba najbardziej znany przykład na to, że zmienne zamykane są przez referencję, a nie przez wartość. Wszystkie cztery funkcje wskazują na tę samą zmienną <code>b_i</code> i są od niej zależne aż po swój kres. Dobrze o tym pamiętać, bo jest to źródłem wielu błędów.</p>
<p>Jeśli jednak chcemy aby funkcje zwracały odpowiednio: <code>0, 1, 2, 3</code>, to co zrobić aby naprawić powyższy przykład? Zastosować kolejne domknięcie, tym razem jednak przekazując naszą zmienną jako argument, ponieważ te przekazywane są przez wartość (tylko typy proste).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    b_i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> b_i <span style="color: #339933;">&lt;</span> b.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>b_i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    b<span style="color: #009900;">&#91;</span>b_i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> i<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span>b_i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 2</span></pre></div></div>

<h2>Zasięg blokowy w JavaScriptcie</h2>
<p>Życie z niedoskonałym zasięgiem funkcyjnym (czasem połączonym z domknięciami) bywa nieprzyjemne. W poprzednim przykładzie musieliśmy dodać nadmiarową funkcję, co oznacza zaciemnienie kodu oraz spadek wydajności. Tak samo musielibyśmy się zachować gdybyśmy chcieli aby pętla <code>for</code> mogła iterować po wartości, która nie przesłoniłaby nam innej, zdefiniowanej wcześniej.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span>
...
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
...
<span style="color: #660066;">console</span>.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 5! 10 zostało przesłonięte</span></pre></div></div>

<p>Twórcy EcmaScriptu szukali więc wyjścia i już w wersji EcmaScript 4 (trochę <a href="http://code42.pl/2010/12/19/obiektowy-javascript-i-wlasciwosci-chronione-w-poszukiwaniu-swietego-graala/">historii porzuconego standardu</a>) zamierzali wprowadzić słowo kluczowe <code>let</code> mające służyć deklarowaniu zmiennej o zasięgu lokalnym &ndash; blokowym. Standard (a w zasadzie jego zalążek) został niestety porzucony na kilka lat i w okrojonym stanie wróci pod nazwą EcmaScript 6 aka Harmony (mój kolejny pomysł na wpis :).</p>
<p>Okazuje się jednak, że część porzuconego EcmaScriptu 4 została zaimplementowana w silniku Firefoksa. Są to <a href="https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.7">JavaScript 1.7</a> i <a href="https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.8">JavaScript 1.8</a>. Zmienne lokalne są częścią wersji 1.7 i po przestawieniu silnika w odpowiedni tryb można z nich do woli korzystać. Co ciekawe silnik RingoJS domyślnie działa w wersji 1.8, co dawałoby mu ogromną przewagę nad silnikiem Node&#8217;a, gdyby nie jego słaba wydajność :).</p>
<p>Przykład wykorzystania <code>let</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript;version=1.8&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        b_i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> b_i <span style="color: #339933;">&lt;</span> b.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>b_i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        let i <span style="color: #339933;">=</span> b_i<span style="color: #339933;">;</span>
        b<span style="color: #009900;">&#91;</span>b_i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> i<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; 2</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; ReferenceError</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Ciekawym pytaniem na koniec jest, czy zasięg funkcyjny ma jakiś sens? Czy wraz z wejściem zmiennych lokalnych nie powinniśmy porzucić <code>var</code>?</p>
<p>Ciąg dalszy nastąpi&#8230;</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/' rel='bookmark' title='Co lepiej wiedzieć o JavaScriptcie cz.2.: hoisting, deklaracje funkcji i wyrażenia funkcyjne'>Co lepiej wiedzieć o JavaScriptcie cz.2.: hoisting, deklaracje funkcji i wyrażenia funkcyjne</a></li>
<li><a href='http://code42.pl/2009/03/18/konsola-firebuga-echowanie-javascriptu/' rel='bookmark' title='Konsola Firebuga &#8211; &#8222;echowanie&#8221; Javascriptu'>Konsola Firebuga &#8211; &#8222;echowanie&#8221; Javascriptu</a></li>
<li><a href='http://code42.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/' rel='bookmark' title='Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem'>Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JavaScript po polsku</title>
		<link>http://code42.pl/2011/08/05/javascript-po-polsku/</link>
		<comments>http://code42.pl/2011/08/05/javascript-po-polsku/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 23:19:45 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1055</guid>
		<description><![CDATA[Przypadkiem zacząłem na forumweb.pl zbierać zagadnienia związane z JavaScriptem, o których nic jeszcze po polsku nie napisano, bądź napisano niewystarczająco dużo. Na razie mam 8: hoisting i function declaration vs definition, function and block scope + closures, dziedziczenie &#8211; zaległa część serii o obiektowym JavaScriptcie (cz.1., cz.2.), setTimeout vs setInterval &#8211; najpewniej pokusiłbym się o [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/' rel='bookmark' title='Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem'>Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem</a></li>
<li><a href='http://code42.pl/2010/12/19/obiektowy-javascript-i-wlasciwosci-chronione-w-poszukiwaniu-swietego-graala/' rel='bookmark' title='Obiektowy JavaScript i właściwości chronione &#8211; w poszukiwaniu Świętego Graala'>Obiektowy JavaScript i właściwości chronione &#8211; w poszukiwaniu Świętego Graala</a></li>
<li><a href='http://code42.pl/2010/12/22/zarezerwowane-slowa-kluczowe-w-javascript-gramatyka-jezyka/' rel='bookmark' title='Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka'>Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Przypadkiem zacząłem na <a href="http://www.forumweb.pl/viewtopic.php?p=376774">forumweb.pl</a> zbierać zagadnienia związane z JavaScriptem, o których nic jeszcze po polsku nie napisano, bądź napisano niewystarczająco dużo. Na razie mam 8:</p>
<ul>
<li><a href="http://code42.pl/2011/08/20/co-lepiej-wiedziec-o-javascriptcie-cz-2-hoisting-deklaracje-funkcji-i-wyrazenia-funkcyjne/"><strong>hoisting i function declaration vs definition</strong></a>,</li>
<li><a href="http://code42.pl/2011/08/09/co-lepiej-wiedziec-o-javascriptcie-cz-1-typy-zasiegu-i-domkniecia/"><strong>function and block scope</strong> + <strong>closures</strong></a>,</li>
<li><strong>dziedziczenie</strong> &ndash; zaległa część serii o obiektowym JavaScriptcie (<a href="http://code42.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/">cz.1.</a>, <a href="http://code42.pl/2010/03/02/obiektowy-javascript-cz-2-klasa-sama-w-sobie/">cz.2.</a>),</li>
<li><strong>setTimeout vs setInterval</strong> &ndash; najpewniej pokusiłbym się o tłumaczenie <a href="http://ejohn.org/blog/how-javascript-timers-work/">artykułu Johna Resiga</a> z dodatkowymi wstawkami np. o <code>requestAnimationFrame</code>,</li>
<li><a href="http://blog.kamilbrenk.pl/cross-domain-javascript-cors/"><strong>CORS lekarstwem na SOP</strong> (artykuł Kamila Brenka)</a> &ndash; z uwydatnieniem tego który serwer musi odpowiednio odpowiadać oraz opisem preflighted requests,</li>
<li><strong>EcmaScript Harmony i JavaScript 1.8</strong>,</li>
<li><strong>obsługa klawiatury</strong> &ndash; ze zwróceniem na przytrzymywanie i powtarzanie,</li>
<li><strong>typ <code>Number</code></strong> &ndash; dlaczego <code>Math.pow(2, 53) == Math.pow(2, 53) + 1</code>? :)</li>
</ul>
<p>Mam wielką ochotę napisać na każdy z tych tematów. Boję się może jedynie dziedziczenia, którego sprawa jest na tyle kompleksowa, że praca nad artykułem mogłaby mnie wessać na wieki :). Cierpię jednak na chroniczny brak czasu, więc zachęcam również innych do podejmowania powyższych tematów. Do każdego mam już w głowie przygotowany krótszy, bądź dłuższy konspekt, którym mogę się podzielić.</p>
<p>Interesuje mnie również, czy macie pomysł na inne tematy, których opracowań brakuje w polskim internecie. Gdyby też jakieś z powyższych zagadnień było już w stopniu wystarczającym opisane po polsku proszę o komentarze. Nie ma się co powtarzać.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/' rel='bookmark' title='Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem'>Obiektowy Javascript cz.1. &#8211; obiekt Twoim przyjacielem</a></li>
<li><a href='http://code42.pl/2010/12/19/obiektowy-javascript-i-wlasciwosci-chronione-w-poszukiwaniu-swietego-graala/' rel='bookmark' title='Obiektowy JavaScript i właściwości chronione &#8211; w poszukiwaniu Świętego Graala'>Obiektowy JavaScript i właściwości chronione &#8211; w poszukiwaniu Świętego Graala</a></li>
<li><a href='http://code42.pl/2010/12/22/zarezerwowane-slowa-kluczowe-w-javascript-gramatyka-jezyka/' rel='bookmark' title='Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka'>Zarezerwowane słowa kluczowe w JavaScript &#8211; gramatyka języka</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/08/05/javascript-po-polsku/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Node.js i middle-end – przenośny kod i emulacja przeglądarki</title>
		<link>http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/</link>
		<comments>http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 22:50:44 +0000</pubDate>
		<dc:creator>Piotrek Reinmar Koszuliński</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[devcamp]]></category>
		<category><![CDATA[global]]></category>
		<category><![CDATA[kontekst]]></category>
		<category><![CDATA[middle-end]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[ssjs]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=980</guid>
		<description><![CDATA[DevCamp Chciałbym zacząć od tego, że pojawiły się już pierwsze podsumowania researchów, jakie wykonaliśmy na DevCampie o ServerSide JavaScript (Node, v8cgi, RhinoJS). W tej chwili dostępnych jest 5 (z 22) tematów: Testy wydajności środowisk (CPU oraz I/O) Testy systemów generowania szablonów Protokoły Pisanie bezpiecznego kodu Zabezpieczanie kodu źródłowego Czym w ogóle był DevCamp? 20 doświadczonych [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/' rel='bookmark' title='Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS'>Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS</a></li>
<li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2011/08/29/javascript-na-jesien-2011/' rel='bookmark' title='JavaScript na jesień 2011'>JavaScript na jesień 2011</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h2>DevCamp</h2>
<p>Chciałbym zacząć od tego, że pojawiły się już pierwsze podsumowania researchów, jakie wykonaliśmy na <strong><a href="http://devcamps.pl/">DevCampie</a> o ServerSide JavaScript (Node, v8cgi, RhinoJS)</strong>. W tej chwili dostępnych jest 5 (z 22) tematów:</p>
<ul>
<li><a href="http://devcamps.pl/topics/perf_io_cpu">Testy wydajności środowisk (CPU oraz I/O)</a></li>
<li><a href="http://devcamps.pl/topics/perf_templates">Testy systemów generowania szablonów</a></li>
<li><a href="http://devcamps.pl/topics/int_protocols">Protokoły</a></li>
<li><a href="http://devcamps.pl/topics/sec_coding">Pisanie bezpiecznego kodu</a></li>
<li><a href="http://devcamps.pl/topics/sec_source_enc">Zabezpieczanie kodu źródłowego</a></li>
</ul>
<p>Czym w ogóle był DevCamp?</p>
<blockquote><p>20 doświadczonych developerów spotkało się, by przebadać kwestie związane z praktycznym zastosowaniem JavaScriptu. Opracowaliśmy 18 tematów, zaimplementowaliśmy 4 różne wersje Twittera oparte o różne technologie ServerSide JavaScript. Prawie 40 godzin kodowania, kilka tysięcy commitów do repozytorium</p>
</blockquote>
<p>Od siebie mogę dodać, że to były bardzo pobudzające 3 dni, podczas których wiele się nauczyłem. Rzadko ma się okazję spotkać tylu świetnych programistów JavaScript (i developerów w ogóle) i posłuchać co mają do powiedzenia.</p>
<p>Mając do dyspozycji całe 3 dni pierwsze dwa poświęciliśmy na typowy research, a trzeci na podsumowujące implementacje twitterów (miało nie być czata, a wyszedł norealtime&#8217;owy czat ;). Research podzielony był na 5 tematów: <strong>wydajność, bezpieczeństwo, bazy danych, integracja (middleware, middle-end, obsługa protokołów itp.) i projekty (organizacja kodu, hosting, testowanie itp.)</strong>. Pierwszy jest oczywiście chwytliwy i nie brakowało na niego chętnych, następne dwa mnie mniej interesowały, a skupić postanowiłem się na dwóch ostatnich. Prace nad nimi natchnęły mnie do napisania artykułu i oto właśnie on.</p>
<h2>Middle-end</h2>
<p>Aby się nie powtarzać, pozwolę sobie zacytować siebie samego z nieopublikowanego jeszcze (<ins><a href="http://devcamps.pl/topics/int_middle_end">już opublikowanego</a></ins>) podsumowania jednego z DevCampowych tematów:</p>
<p><span id="more-980"></span> </p>
<blockquote><p>Jedną z najbardziej interesujących zalet jakie wnosi idea SSJS jest możliwość wykorzystania tego samego kodu zarówno po stronie przeglądarki jak i po stronie serwera. Daje to możliwość współdzielenia części logiki, modelu, walidatorów, czy warstwy widoku. Najprościej przedstawia się sytuacja kiedy od razu napiszemy cały backend w JavaScriptcie, jednak w praktyce częściej będziemy integrować Node.js, czy inne rozwiązanie SSJS, z już istniejącą aplikacją.</p>
<p>Taką warstwę, znajdującą się pomiędzy backendem i frontendem, z zachowaniem pełnej logiki rozumowania, nazywamy middle-endem (po więcej informacji odsyłamy do <a href="http://blog.getify.com/2010/07/what-exactly-is-the-middle-end/">twórcy tej koncepcji</a>). Zwróćmy też uwagę by nie mylić middle-endu z middlewarem.</p>
</blockquote>
<p>Aby myśleć o użyciu tego samego kodu po stronie przeglądarki i serwera musimy zadbać o dwie rzeczy &ndash; uruchamianiu skryptów w Nodzie w takim kontekście w jakim odbywa się to w przeglądarce (i najlepiej zupełnie oddzielonym od globalnego) oraz o odpowiednią architekturę naszego kodu, by był on przenośny. Pierwszą kwestię postaram się bardzo dokładnie zbadać w tym artykule. Drugą jedynie napocznę i może do niej wrócę kiedy nabiorę więcej projektowego doświadczenia w tym temacie.</p>
<h2>Kontekst przeglądarki</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span> <span style="color: #339933;">===</span> window<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">a</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>window<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Co otrzymamy jeśli ten kod uruchomimy w przeglądarce? Oczywiście będą to po kolei: <code>true, 1, DOMWindow</code>. To samo zachowanie chcielibyśmy uzyskać w Nodzie. Pierwszym naszym zadaniem będzie uzyskanie obiektu <code>window</code>, a więc implementacji DOM-a. Z pomocą przyjdzie nam moduł <a href="https://github.com/tmpvar/jsdom">JSDOM</a>, który mieliśmy okazję przetestować na DevCampie i który na tę chwilę implementuje  DOM level 1 i 2 w 100%, DOM level 3 w 14%. Modułu tego możemy użyć przykładowo tak:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">jsdom</span><span style="color: #339933;">,</span>
    document <span style="color: #339933;">=</span> jsdom<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;hello world&lt;/body&gt;&lt;/html&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    window <span style="color: #339933;">=</span> document.<span style="color: #660066;">createWindow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">document</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; '&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;hello world&lt;/body&gt;&lt;/html&gt;'</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">innerWidth</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; 1024</span></pre></div></div>

<p>Następnie chcielibyśmy uruchomić skrypty w kontekście otrzymanego obiektu <code>window</code>. JSDOM w teorii posiada taką możliwość:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
jsdom.<span style="color: #660066;">env</span><span style="color: #009900;">&#40;</span>
    <span style="color: #3366CC;">'&lt;p&gt;&lt;a class=&quot;the-link&quot; href=&quot;http://jsdom.org&gt;JSDOM<span style="color: #000099; font-weight: bold;">\'</span>s Homepage&lt;/a&gt;&lt;/p&gt;'</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#91;</span>
        <span style="color: #3366CC;">'http://code.jquery.com/jquery-1.5.min.js'</span>
    <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>errors<span style="color: #339933;">,</span> window<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;contents of a.the-link:&quot;</span><span style="color: #339933;">,</span> window.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;a.the-link&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Próba uruchomienia tego skryptu na dzień dzisiejszy kończy się&#8230; Błędem JSDOM-a.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">TypeError: Cannot call method <span style="color: #ff0000;">'runInContext'</span> of undefined
at Object.javascript <span style="color: #7a0874; font-weight: bold;">&#40;</span>... lib<span style="color: #000000; font-weight: bold;">/</span>jsdom<span style="color: #000000; font-weight: bold;">/</span>level2<span style="color: #000000; font-weight: bold;">/</span>languages<span style="color: #000000; font-weight: bold;">/</span>javascript.js:<span style="color: #000000;">17</span>:<span style="color: #000000;">14</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Co ciekawe ten sam przykład działał nam na DevCampie, a wynika to z braku zgodności pomiędzy wersjami 0.5 i 0.4.9 Node&#8217;a. Przy czym kiedy popatrzymy na <a href="https://github.com/tmpvar/jsdom/commit/a5a092234f48ae900e62d4c734bc8ce1da657a72">historię modułu odpowiedzialnego za uruchamianie skryptów w JSDOM-ie</a>, zobaczymy, że błąd ten został już naprawiony. Niestety od lutego tego roku nie została wydana żadna nowa wersja modułu.</p>
<p>Z ciekawości spróbowałem jeszcze uruchomić trunkową wersję JSDOM-a i niestety jest z nią <a href="https://github.com/tmpvar/jsdom/issues/248">wiele problemów</a>. Tak więc w tej chwili radzę unikać wykonywania skryptów przy pomocy tego modułu.</p>
<h2>Sandbox w Node.js</h2>
<p>Opis problemów JSDOM-a tak naprawdę był jedynie anegdotą o tym jak niestabilne i zmienne jest to środowisko. Uważam, że (przynajmniej przy obecnym API JSDOM-a) skrypty powinniśmy uruchamiać sami. Podstawową zaletą tego rozwiązania jest to, że mamy wtedy pełną kontrolę nad kontekstem uruchomienia. Przykładowo mamy możliwość przekazania obiektu <code>console</code> z globalnego kontekstu Node&#8217;a, tak by uruchamiane skrypty mogły logować na konsolę systemową. Co prawda przekazując ten obiekt do uruchamianych skryptów narażamy się na to, że kod jakiegoś nieogarniętego programisty zmieni nam coś w globalnym kontekście Node&#8217;a. Przy pomocy <code>Object.freeze()</code> możemy się jednak przed tym zabezpieczyć (chyba że ktoś będzie np. specjalnie szukać dziur).</p>
<p>Do uruchamiania skryptów możemy wykorzystać moduł <a href="http://nodejs.org/docs/v0.5.1/api/vm.html">VM</a>, z którego nas będzie interesować metoda <code>runInNewContext(code, [sandbox], [filename])</code>. Sposób jej użycia jest następujący:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a++; b = false;'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; { a: 2, b: false }</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; true</span></pre></div></div>

<p>Z ciekawości sprawdźmy jakie zmienne mamy dostępne w naszym nowym globalnym kontekście. W tym celu do kontekstu wywołania przekażmy obiekt <code>console</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
    console<span style="color: #339933;">:</span> console
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; {}</span></pre></div></div>

<p>Takie zachowanie może zdziwić i w bardzo specyficznych przypadkach mogłoby spowodować problemy z działaniem jakiegoś kodu. Jest jednak naturalne dla Node&#8217;a (choć nie dla mnie, bo go nie rozumiem &ndash; to nie wygląda na kwestię bezpieczeństwa), ale do obejścia:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'for (var i in this) console.log(i);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; a, console, i</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(Object.keys(this));'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; [a, console, i]</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'var b = 1; console.log(Object.keys(this));'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; [ 'a', 'console', 'i', 'b' ]</span></pre></div></div>

<p>Z ciekawości dopisałem <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/example3.js">kilka testów</a> jak zachowują się w Nodzie <code>this</code> i <code>global</code> (tak naprawdę to to jest globalny kontekst w Nodzie) i moją uwagę zwróciły dwa zachowania. Po pierwsze przy uruchamianiu skryptów z konsoli Node&#8217;a <code>this === global</code>, co nie jest prawdą przy uruchamianiu z pliku. Po drugie poniższy skrypt:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>global.<span style="color: #660066;">a</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; ?</span></pre></div></div>

<p>Również inaczej zachowa się przy uruchamianiu z konsoli, niż przy uruchamianiu z pliku. W pierwszym przypadku otrzymamy <code>1</code>, w drugim <code>undefined</code>. Dzięki temu można wysnuć teorię, że konsola Node&#8217;a działa właśnie w oparciu o moduł VM. Innym powodem (bądź jednym z powodów) może być to, że kod z plików uruchamiany jest jak moduł Node&#8217;a (dzięki <a href="http://twitter.com/medikoo">medikoo</a> za przypomnienie). Zabezpiecza nam to globalnego scope&#8217;a przed zaśmieceniem. Jako ciekawostkę mogę podać, że na DevCampie komuś przy debugowaniu kodu wyszło, że moduły są po prostu otaczane mniej więcej takim kodem: <code>(function () { ... }).apply({})</code>.</p>
<h2>Reverse engineering modułu VM</h2>
<p>Wróćmy jeszcze na chwilę do:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; {}</span></pre></div></div>

<p>Udało mi się też odkryć sposób aby skrypt wykonany został w ten sposób by <code>console.log(this)</code> nie było pustym obiektem. Kiedy szukałem rozwiązania zacząłem od takiego kodu:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	console<span style="color: #339933;">:</span> console
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
ctx.<span style="color: #660066;">g</span> <span style="color: #339933;">=</span> ctx<span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; {}</span></pre></div></div>

<p>Niestety wciąż dostawałem <code>{}</code> i zachowania Node&#8217;a w tym wypadku nie potrafię wyjaśnić w czysto JavaScriptowy sposób:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(&quot;g&quot; in this);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; true</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(Object.getOwnPropertyDescriptor(this, &quot;g&quot;));'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// -&gt; { value: {},</span>
<span style="color: #006600; font-style: italic;">//      writable: true,</span>
<span style="color: #006600; font-style: italic;">//      enumerable: true,</span>
<span style="color: #006600; font-style: italic;">//      configurable: true }</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this.g === this);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; true</span>
&nbsp;
Object.<span style="color: #660066;">defineProperty</span><span style="color: #009900;">&#40;</span>ctx<span style="color: #339933;">,</span> <span style="color: #3366CC;">'h'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> value<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> enumerable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this.h /*, h*/);'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; undefined, Error</span></pre></div></div>

<p>Nic nie da też zabawa z prototypem &ndash; raz, że <code>ctx.__proto__ = ctx</code> wyrzuci błąd, a dwa, że co prawda możemy prototyp sklonować, ale nic to nie zmieni. <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/example5.js">Kod powyższych testów znajduje się na Githubie</a>.</p>
<p>Zbawieniem okazało się dopiero domknięcie:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	console<span style="color: #339933;">:</span> console<span style="color: #339933;">,</span>
	g<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> ctx<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'console.log(this.g());'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I gdyby ktoś bardzo chciał mieć pełny obiekt globalny, to może skorzystać z poniższego kodu. Ostrzegam jednak, że od patrzenia na niego bolą oczy, a jego ograniczenia powodują, że jest bezużyteczny :D.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> runWithGlobal <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>code<span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> vm <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    ctx.<span style="color: #660066;">g</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> ctx<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    vm.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'(function (g) { delete this.g;'</span> <span style="color: #339933;">+</span>
        code <span style="color: #339933;">+</span>
    <span style="color: #3366CC;">'}).call(g());'</span><span style="color: #339933;">,</span> ctx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Jak działa VM?</h2>
<p>Po co w zasadzie o tym piszę? Otóż ponownie daje nam to pewien obraz tego w jaki sposób <code>vm.runInNewContext</code> uruchamia skrypty, a niestety tych informacji nie znajdziemy w dokumentacji. Otóż Node najprawdopodobniej kopiuje sobie do kontekstu właściwości z podanego obiektu. Co ciekawe robi to z pominięciem niewyliczalnych właściwości (test: <code>this.h === undefined</code>). W dodatku zwraca uwagę na odwołania cykliczne (przynajmniej w stosunku do samego obiektu globalnego) i aktualizuje je do nowo utoworzonego obiektu. Następnie w jakiś niejavascriptowy sposób ukrywa te zmienne w <code>this</code>, po czym wykonuje skrypt. Na sam koniec, z tego co udało mi się wyczytać, z powrotem przekopiowuje te zmienne do obiektu podanego jako kontekst. Przy wykonywaniu skryptu Node pozwala korzystać i z pełnego obiektu kontekstu (który można przekazać jedynie przez domknięcie), i z innych obiektów, w żaden sposób ich nie zabezpieczając. Możliwe są więc takie odwołania poza nowy kontekst wywołania, które mogą powodować pewne zagrożenia:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> obj1 <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    obj2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ctx2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    console<span style="color: #339933;">:</span> console<span style="color: #339933;">,</span>
    obj1<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> obj1<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    obj2<span style="color: #339933;">:</span> obj2<span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'vm'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">runInNewContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'obj1().a += 100; obj2.a += 200;'</span><span style="color: #339933;">,</span> ctx2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>obj1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; { a: 101 }</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>obj2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// -&gt; { a: 201 }</span></pre></div></div>

<h2>To już koniec? Mamy przeglądarkę?</h2>
<p>Pomijając ten drobny fakt, że globalne zmienne są z niewyjaśnionych powodów niewyliczalne, możemy uznać, że potrafimy uruchamiać skrypty w sposób w jaki robi to przeglądarka. Stworzyłem więc dwa pliki testowe, by mieć pewność, że zachowanie kontekstu będzie poprawne. Skrypty znajdują się <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/script.js">tu</a> i <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/script2.js">tu</a>. Wykonywane są jeden po drugim tak by sprawdzić, że kontekst jest odpowiednio współdzielony.</p>
<p><a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/test2.js">Kod uruchamiający skrypty</a> wygląda w skrócie tak:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> testScope <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>scope<span style="color: #339933;">,</span> <span style="color: #000066;">name</span><span style="color: #339933;">,</span> log<span style="color: #339933;">,</span> method<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    method <span style="color: #339933;">=</span> method <span style="color: #339933;">||</span> <span style="color: #3366CC;">'runInNewContext'</span><span style="color: #339933;">;</span>
    vm<span style="color: #009900;">&#91;</span>method<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>code1<span style="color: #339933;">,</span> scope<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    vm<span style="color: #009900;">&#91;</span>method<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>code2<span style="color: #339933;">,</span> scope<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'separate globals:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>.<span style="color: #660066;">e</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Stworzyłem też <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/test2.html">wersję dla przeglądarki</a>, aby porównać wyniki.</p>
<h3>Test 1 &ndash; porażka</h3>
<p>Pierwszy test kontekstu, korzystając z tego co się dowiedzieliśmy:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> window <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
		a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
		b<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span>
		console<span style="color: #339933;">:</span> console<span style="color: #339933;">,</span>
		assert<span style="color: #339933;">:</span> assert
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	window.<span style="color: #660066;">window</span> <span style="color: #339933;">=</span> window<span style="color: #339933;">;</span>
&nbsp;
	testScope<span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #3366CC;">'1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Wynik:</span>
<span style="color: #006600; font-style: italic;">//AssertionError: {}.e === 1 (24 linia script2.js)</span></pre></div></div>

<p>Ten sposób uruchamiania skryptów nie przeszedł testów współdzielenia zmian w prototypach natywnych obiektów. W <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/script.js">script.js</a> dodaję do <code>Object.prototype</code> właściwość <code>e = 1</code>. Niestety nie jest ona dostępna w obiekcie utworzonym w <a href="https://github.com/Reinmar/ideas/blob/master/node-vm-ctx/script.js">script2.js</a>.</p>
<h3>Test 2 &ndash; nieudokumentowane metody zwane ficzerami</h3>
<p>Okazuje się jednak, że istnieje jeszcze trzecia (poza <code>runInThisContext()</code>, o której nie wspomniałem, bo nie jest interesująca w tym temacie) metoda uruchamiania skryptów, która nie została udokumentowana. Jest to <code>runInContext(code, ctx)</code>, przy czym drugim argumentem musi być obiekt utworzony przez również nieudokumentowaną metodę <code>createContext(obj)</code>. Całość możemy uruchomić tak:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> window <span style="color: #339933;">=</span> vm.<span style="color: #660066;">createContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		a<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
		b<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span>
		console<span style="color: #339933;">:</span> console<span style="color: #339933;">,</span>
		assert<span style="color: #339933;">:</span> assert
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	window.<span style="color: #660066;">window</span> <span style="color: #339933;">=</span> window<span style="color: #339933;">;</span>
&nbsp;
	testScope<span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #3366CC;">'3'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'runInContext'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Okazuje się, że tym razem wszystkie testy przechodzą. Dlaczego te metody są nieudokumentowane i co w ogóle robią w Nodzie? To świetne pytanie do twórców, którzy <a href="https://github.com/joyent/node/issues/1353">sami na razie nie są pewni</a>.</p>
<p>Myślę, że tym pozytywnym akcentem zakończę przydługą część o wspaniale udokumentowanym module VM :). Jeśli wyniki moich pedantycznych testów zainteresują choćby 10 osób, to trochę mnie to zdziwi. Pora na kilka moich przemyśleń dotyczących przenośności kodu pomiędzy środowiskami.</p>
<h2>Przenośny kod</h2>
<p>Na początku artykułu napisałem, że wspomnę o architekturze. Tak naprawdę na chwilę obecną mam jedynie kilka obserwacji i pomysłów. Dopiero możliwość ich zastosowania w praktyce pozwoli mi się przekonać ile w nich prawdy i sensu.</p>
<p>Przede wszystkim należy się zastanowić, czy w ogóle potrzebujemy specjalnego uruchamiania kodu w wydzielonym kontekście zbliżonym do tego w przeglądarce? To zależy w znacznej mierze od projektu. Jeśli mamy już wiele tysięcy linii niepewnego kodu JavaScript i nie ma takiej opcji byśmy zbyt mocno ingerowali w jego architekturę, a chcemy podpiąć jakoś Node&#8217;a, wtedy najlepiej dla nas będzie jeśli kod odseparujemy od kontekstu Node&#8217;a. Zabezpieczymy się tym samym przed bezsensownymi modyfikacjami globali, przed zaśmiecaniem globalnego kontekstu, a sam kod będzie działał w przyjaźniejszym mu środowisku, zbliżonym jak najbardziej do oryginalnego.</p>
<p>Jeśli kod został dobrze napisany, bądź dopiero siadamy do projektu i możemy przemyśleć podejście i od początku je testować, wtedy sposób uruchomienia współdzielonego kodu nie musi być tak bardzo faszystowski. Pliki ze skryptami dla przeglądarki, jeśliby zostały napisane na modłę CommonJSową, możnaby przecież bezpośrednio dołączać do Node&#8217;a.</p>
<p>Pojawia się w takim razie pytanie w jaki sposób moduły CommonJSowe, które w Nodzie ładowane są synchronicznie, ładować w przeglądarce asynchronicznie? Chyba najpopularniejsze w tej chwili rozwiązanie <a href="http://requirejs.org/">RequireJS</a> umożliwia przekonwertowanie CommonJSowych skryptów na takie, które będą mogły być sensownie ładowane w przeglądarce. Nie znam API RequireJS, nie wiem czy konwersja działa sprawnie, ale uważam, że w tej chwili (dopóki ECMAScript Harmony nie udostępni swoich modułów) konwertowanie ma najwięcej sensu.</p>
<p>Na jakiej zasadzie mogłaby działać taka konwersja? Na przykład można zawartość pliku otoczyć wywołaniem funkcji przekazywanej do metody dodatkowej biblioteki. W dodatku wszystkie wywołania <code>require()</code> należałoby odnaleźć i dodać jako argument do wywołania tej metody. Callback z ciałem modułu powinien się wykonać dopiero po pobraniu się kodu wszystkich zależności. Przykładowo dla oryginalnego modułu:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> math <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'math'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    async <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'async'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
async.<span style="color: #660066;">sth</span><span style="color: #009900;">&#40;</span>math.<span style="color: #660066;">sth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
...
&nbsp;
<span style="color: #660066;">exports</span>.<span style="color: #660066;">sth</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>Kod wynikowy mógłby wyglądać tak:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Require.<span style="color: #660066;">load</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">'math'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'async'</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>require<span style="color: #339933;">,</span> exports<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//module----</span>
    <span style="color: #003366; font-weight: bold;">var</span> math <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'math'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        async <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'async'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    async.<span style="color: #660066;">sth</span><span style="color: #009900;">&#40;</span>math.<span style="color: #660066;">sth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ...
&nbsp;
    <span style="color: #660066;">exports</span>.<span style="color: #660066;">sth</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">//module----</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> exports<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Napisanie funkcji wrapującej wydaje mi się trywialne. Nie mam co prawda pewności, że ten sposób nie ma jakichś ograniczeń, ale wszystko jest do sprawdzenia. W dodatku prawdopodobne jest, że RequireJS działa w zbliżony sposób do przedstawionego przeze mnie, ale daruję sobie sprawdzanie tego :).</p>
<p>Ostatnią rzeczą o jakiej chciałbym jeszcze napisać jest to, czego unikać by kod dało się na przykład jak najłatwiej przenieść z przeglądarki do standardu CommonJS.</p>
<ul>
<li>Nie korzystaj z niejavascriptowych globali. Jeśli co linię masz odwołanie do <code>document</code>, <code>escape()</code>, czy po prostu <code>window</code>, to Twój kod trudniej będzie przeportować do innego środowiska. Przyznam, że dopiero teraz, kiedy musiałem zmierzyć się z przenośnością kodu zrozumiałem dlaczego <a href="http://www.jslint.com/">JSLint</a> jest tak restrykcyjny pod tym względem. To naprawdę ma sens.</li>
<li>Nie używaj <code>this</code> w globalnym kontekście &ndash; ani jako zamiennika dla <code>window</code>, ani do inicjalizacji zmiennych. Nie robi tego Node (najprawdopodobniej by rozdzielić zadanie obiektu globalnego od <code>this</code>, który ma inną rolę i tym samym zabezpieczyć się też przed przypadkowym zaśmiecaniem globalnego kontekstu), nie rób i Ty. Przyjmij nawet tę samą konwencję nazewniczą i zamykaj swoje skrypty np. w: <code>(function (global) { ... }).call({}, window);</code></li>
<li>Nie współdziel wielu zmiennych pomiędzy plikami (najlepiej tylko jedną, traktowaną jak <code>exports</code>), a łatwiej będzie Ci je potraktować jako moduły.</li>
</ul>
<h2>Podsumowanie</h2>
<p>Na dniach pojawi się podsumowanie tematu middle-end z DevCampu, który to natchnął mnie do napisania tego przydługiego artykułu. Tak naprawdę prawie każda z poruszonych przeze mnie kwestii jakoś dotyczyła tego, z czym zetknęliśmy się podczas prac nad implementacją middle-endu, w postaci jaką sobie założyliśmy. Gdybyśmy nie chcieli symulować sytuacji, w której podpinamy się pod już działającą aplikację moglibyśmy podejść w ten prostszy sposób i spróbować wykorzystać np. RequireJS. Mogłoby się okazać, że rozwiązałby wszystkie nasze problemy dotyczące architektury aplikacji.</p>
<p>Osobiście myślę, że middle-end jako idea współdzielenia tej części aplikacji, która potrzebna jest i z przodu, i z tyłu, to przyszłość. Podobnie jak Getify twierdzę, że w każdej aplikacji middle-end gdzieś istnieje i naszym zadaniem jest go znaleźć, określić i wydzielić. Pytanie na przyszłość, jak to zrobić by się nie narobić i zrobić to dobrze :)</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2011/09/20/zapraszam-na-darmowe-szkolenie-devmeeting-middle-end-w-oparciu-o-nodejs/' rel='bookmark' title='Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS'>Zapraszam na darmowe szkolenie DevMeeting &ndash; middle-end w oparciu o NodeJS</a></li>
<li><a href='http://code42.pl/2012/01/25/moja-prezentacja-o-node-js-z-meet-js-i-gtug-wroclaw/' rel='bookmark' title='Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław'>Moja prezentacja o Node.JS z Meet.JS i GTUG Wrocław</a></li>
<li><a href='http://code42.pl/2011/08/29/javascript-na-jesien-2011/' rel='bookmark' title='JavaScript na jesień 2011'>JavaScript na jesień 2011</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/07/19/node-js-i-middle-end-przenosny-kod-i-emulacja-przegladarki/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

