<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>cjohansen.no</title>
    <link>http://www.cjohansen.no</link>
    <description>
       En blogg om programmering, web og film
    </description>
    <atom:link href="http://www.cjohansen.no/rss.xml" rel="self" type="application/rss+xml" />
    <language>no-nb</language>
    <copyright>Copyright 2006-2009 Christian Johansen</copyright>
                <item>
  <pubDate>21 Mar 2009 00:32:52 GMT</pubDate>
  <title>Et bedre utviklingsmiljø for Rails</title>
  <link>http://www.cjohansen.no/rails/et_bedre_utviklingsmiljoe_for_rails</link>
  <guid>http://www.cjohansen.no/rails/et_bedre_utviklingsmiljoe_for_rails</guid>
  <comments>http://www.cjohansen.no/rails/et_bedre_utviklingsmiljoe_for_rails#comments</comments>
  <description>
    
&lt;p&gt;
Den siste uken har jeg snublet over og/eller kommet igang med opp til flere småting som har gjort arbeidsmiljøet mitt for Rails-applikasjoner langt mer behagelig. 			
									&lt;a href=&quot;http://www.cjohansen.no/en/rails/pimp_my_development_environment&quot;&gt;Sjekk tipsene&lt;/a&gt;.
&lt;/p&gt;

    
  </description>
</item>
            <item>
  <pubDate>16 Mar 2009 00:13:13 GMT</pubDate>
  <title>Twibot: Et mikrorammeverk for Twitter-bots i Ruby</title>
  <link>http://www.cjohansen.no/ruby/twibot_et_mikrorammeverk_for_twitter_bots_i_ruby</link>
  <guid>http://www.cjohansen.no/ruby/twibot_et_mikrorammeverk_for_twitter_bots_i_ruby</guid>
  <comments>http://www.cjohansen.no/ruby/twibot_et_mikrorammeverk_for_twitter_bots_i_ruby#comments</comments>
  <description>
    
&lt;p&gt;
Idag slapp jeg Ruby-gemen 			
									&lt;a href=&quot;http://github.com/cjohansen/twibot&quot;&gt;Twibot&lt;/a&gt;. Twibot er et mikrorammeverk for å lage Twitter-boter, med et sexy DSL ala Sinatras. 			
									&lt;a href=&quot;http://www.cjohansen.no/en/ruby/twibot_a_microframework_for_twitter_bots_in_ruby&quot;&gt;Sjekk ut gjennomgangen&lt;/a&gt;.
&lt;/p&gt;

    
  </description>
</item>
            <item>
  <pubDate>10 Mar 2009 09:41:33 GMT</pubDate>
  <title>Ruby Wednesday!</title>
  <link>http://www.cjohansen.no/ruby/ruby_wednesday</link>
  <guid>http://www.cjohansen.no/ruby/ruby_wednesday</guid>
  <comments>http://www.cjohansen.no/ruby/ruby_wednesday#comments</comments>
  <description>
    
&lt;p&gt;
I morgen møtes 16+ engasjerte Rubyprogrammerere i Oslo for å prate om Ruby 1.9 og for å kollektivt hacke 1.9-støtte inn i en gem. Er du på østlandet og interesserer deg for Ruby, bli med!
&lt;/p&gt;

    
&lt;p&gt;
(Via 			
									&lt;a href=&quot;http://irb.no/-/event/show/64779?occurrence_id=597560_ruby-wednesday&quot;&gt;irb.no&lt;/a&gt;) Årets første Ruby wednesday arrangeres hos Skalar 11.mars. På plakaten står Ruby 1.9 og mer.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Program:&lt;/b&gt;
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Språklige “gotchas” i Ruby 1.9&lt;/li&gt;

&lt;li&gt;Nye features i Ruby 1.9&lt;/li&gt;

&lt;li&gt;Hvor mye raskere er 1.9 enn 1.8?&lt;/li&gt;

&lt;li&gt;Hvordan er det med 1.9-støtten i andre Ruby-versjoner?&lt;/li&gt;

&lt;li&gt;Ruby 1.9 og rammeverkene&lt;/li&gt;

&lt;li&gt;Gems i Ruby 1.9. Hva virker, hva virker ikke. Hvordan gjøre en gem 1.9-kompatibel, hvordan dele endringene med andre?&lt;/li&gt;

&lt;li&gt;Pause&lt;/li&gt;

&lt;li&gt;Dugnad: &amp;quot;save a gem&amp;quot;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Det begynner altså med en gjennomgang av hva som er nytt og forandret i Ruby 1.9. Deretter går vi mer praktisk inn på hva som skal til for at vi kan bruke 1.9 i det daglige. 			
									&lt;a href=&quot;http://theexciter.com/&quot;&gt;Johan&lt;/a&gt; og 			
									&lt;a href=&quot;http://www.zmalltalker.com/&quot;&gt;Marius&lt;/a&gt; (fra Shortcut) tar seg av presentasjonen.
&lt;/p&gt;

&lt;p&gt;
Helt til slutt tar vi en hackfest der vi velger ut en Rubygem som ikke fungerer på 1.9 og fikser denne i fellesskap.
&lt;/p&gt;

&lt;p&gt;
Vi kjører pizza-spleiselag fra klokka seks. Bare sjekk menyen på 			
									&lt;a href=&quot;http://irb.no/-/event/show/64779?occurrence_id=597560_ruby-wednesday&quot;&gt;irb.no&lt;/a&gt; og legg igjen din bestilling som kommentar. Husk penger. Vel møtt, håper så mange som mulig dukker opp!
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>01 Mar 2009 23:48:06 GMT</pubDate>
  <title>Juicer - pakkeverktøy for CSS og JavaScript</title>
  <link>http://www.cjohansen.no/ruby/juicer_pakkeverktoey_for_css_og_javascript</link>
  <guid>http://www.cjohansen.no/ruby/juicer_pakkeverktoey_for_css_og_javascript</guid>
  <comments>http://www.cjohansen.no/ruby/juicer_pakkeverktoey_for_css_og_javascript#comments</comments>
  <description>
    
&lt;p&gt;
Etter mye somling og litt koding er jeg endelig klar med første versjon av 			
									&lt;a href=&quot;http://github.com/cjohansen/juicer&quot;&gt;Juicer&lt;/a&gt;, mitt kommandolinjeverktøy for å kombinere og minifisere CSS og JavaScript-filer. En slags &amp;quot;kompilator&amp;quot; om du vil - med syntakskontroll for JavaScript, og en del URL-verktøy for CSS-filer. Frontend-ytelse har nettopp blitt enklere! For en grundig gjennomgang av funksjonaliteten refererer jeg til 			
									&lt;a href=&quot;http://www.cjohansen.no/en/ruby/juicer_a_css_and_javascript_packaging_tool&quot;&gt;gjennomgang på den engelske delen av bloggen&lt;/a&gt;.
&lt;/p&gt;

    
  </description>
</item>
            <item>
  <pubDate>16 Feb 2009 11:01:59 GMT</pubDate>
  <title>Expires-headeren under Apache</title>
  <link>http://www.cjohansen.no/apache/expires_headeren_under_apache</link>
  <guid>http://www.cjohansen.no/apache/expires_headeren_under_apache</guid>
  <comments>http://www.cjohansen.no/apache/expires_headeren_under_apache#comments</comments>
  <description>
    
&lt;p&gt;
Expires-headeren kan brukes til å øke ytelsen på webapplikasjoner drastisk, ved at statiske ressurser (CSS, JavaScript, bilder) caches hos brukeren. Her er en gjennomgang av oppsett under Apache, og noen tips til hvordan du kan tvinge gjennom nytt innhold når innholdet er cachet hos brukeren. 			
									&lt;a href=&quot;http://www.cjohansen.no/en/apache/using_a_far_future_expires_header&quot;&gt;Les hele det engelske innlegget&lt;/a&gt;.
&lt;/p&gt;

    
  </description>
</item>
            <item>
  <pubDate>26 Jan 2009 21:14:43 GMT</pubDate>
  <title>Multi-stage serveroppsett med mod_rails og capistrano</title>
  <link>http://www.cjohansen.no/rails/multi_stage_serveroppsett_med_mod_rails_og_capistrano</link>
  <guid>http://www.cjohansen.no/rails/multi_stage_serveroppsett_med_mod_rails_og_capistrano</guid>
  <comments>http://www.cjohansen.no/rails/multi_stage_serveroppsett_med_mod_rails_og_capistrano#comments</comments>
  <description>
    
&lt;p&gt;
Etter en times leking med 				&lt;code&gt;mod_rails&lt;/code&gt; innså jeg at dette var så genialt som hypen tilsier. Jeg har nå satt opp et multi-stage-miljø med 				&lt;code&gt;mod_rails&lt;/code&gt; og capistrano til produksjonssetting, og tenkte at kanskje også andre ville være interessert i oppsettet. 			
											
			&lt;a href=&quot;http://www.cjohansen.no/en/rails/multi_staging_environment_for_rails_using_capistrano_and_mod_rails&quot; hreflang=&quot;en&quot;&gt;Lese hele innlegget, på engelsk&lt;/a&gt;.
&lt;/p&gt;

    
  </description>
</item>
            <item>
  <pubDate>15 Jan 2009 00:59:23 GMT</pubDate>
  <title>It lives!</title>
  <link>http://www.cjohansen.no/meta/it_lives</link>
  <guid>http://www.cjohansen.no/meta/it_lives</guid>
  <comments>http://www.cjohansen.no/meta/it_lives#comments</comments>
  <description>
    
&lt;p&gt;
Eller &amp;quot;godt nyttår&amp;quot; som det også heter i starten av et nytt år...
&lt;/p&gt;

    
&lt;p&gt;
2009 har fått en stille og rolig start her på berget, men fortvil ikke, jeg har ikke gitt meg enda. Først og fremst vil jeg ønske alle gamle og nye(?) lesere godt nyttår, om enn noe sent.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17975_1&quot;&gt;Sein start&lt;/h2&gt;
&lt;p&gt;
Desember var svært aktiv på cjohansen.no, med JavaScript-julekalenderen. Denne medførte &amp;quot;noe&amp;quot; mer jobb enn forventet, og når det hele var over var jeg for å være ærlig ganske mett på å skrive for en liten stundt. Men den siste tiden har opp til flere emner surret i hodet, selvom jeg enda ikke har fått prioritert tid til å skrive dem ned.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17975_2&quot;&gt;2008&lt;/h2&gt;
&lt;p&gt;
Mange syns det er moro å oppsummere året som gikk, og jeg kan forsåvidt sympatisere med det. Men jeg har ikke tenkt til det, annet enn å notere at jeg skrev en god del artikler ifjor, og du finner dem allesammen i 			
									&lt;a href=&quot;/arkiv&quot;&gt;arkivet&lt;/a&gt;. Selv er jeg ganske godt fornøyd med deler av den nevnte 			
									&lt;a href=&quot;/julekalender/2008&quot;&gt;julekalenderen&lt;/a&gt;, selvom jeg kanskje hadde ønsket meg noe mer input fra dere som leste det. Det er enda ikke for sent!
&lt;/p&gt;
	&lt;h2 id=&quot;toc17975_3&quot;&gt;2009&lt;/h2&gt;
&lt;p&gt;
Det er langt mer interessant å snakke om 2009. Hittil i år har jeg brukt tiden jeg i desember brukte på å blogge til å kode. Aller mest har jeg kodet på 			
									
												
			&lt;a href=&quot;http://github.com/cjohansen/juicer/tree/master&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Juicer&lt;/a&gt;, et prosjekt jeg 			
									&lt;a href=&quot;/julekalender/2008/javascript_organisering_del_2&quot;&gt;såvidt introduserte i julekalenderen&lt;/a&gt;. Juicer er et Ruby-bibliotek og kommandolinje-program for å kombinere, syntakssjekke og minifisere CSS og JavaScript-filer (ved hjelp av blant annet 			
									
												
			&lt;a href=&quot;http://www.julienlecomte.net/yuicompressor/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Yui Compressor&lt;/a&gt; og 			
									
												
			&lt;a href=&quot;http://www.jslint.com/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;JsLint&lt;/a&gt;). Omtrent som en liten kompilator. Jeg tror den blir ganske nyttig, og kommer tilbake med en bedre presentasjon når jeg har nådd målet jeg foreløpig har satt meg. Det er planlagt å skje om ca to uker.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17975_3_1&quot;&gt;Validatious&lt;/h3&gt;
&lt;p&gt;
Jeg har noen planer for valideringsrammeverket mitt, 			
									
												
			&lt;a href=&quot;http://www.validatious.org&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Validatious&lt;/a&gt;, også. For det første har jeg laget en 			
									
												
			&lt;a href=&quot;http://mootools.net&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;MooTools&lt;/a&gt;-bro ala 			
									
												
			&lt;a href=&quot;http://prototypejs.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Prototype.js&lt;/a&gt;-broen som allerede eksisterte, og får vel også lage en for 			
									
												
			&lt;a href=&quot;http://jquery.com/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;jQuery&lt;/a&gt;. I tillegg har jeg skrevet om noe backend-logikk for enhetstestene fra PHP til Ruby via 			
									
												
			&lt;a href=&quot;http://sinatra.rubyforge.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Sinatra&lt;/a&gt; (et lettvekts bibliotek for webapper som er skikkelig morsomt å jobbe med). Til slutt flytta jeg koden fra et lukket svn-repository til det langt hyggeligere og mer åpne 			
									
												
			&lt;a href=&quot;http://github.com/cjohansen/validatious/tree/master&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Github&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Neste skritt på stigen er å pusse opp websiden littegrann, og da først og fremst lage flere eksempler som viser fleksibiliteten i rammeverket.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17975_3_2&quot;&gt;Rails-plugins&lt;/h3&gt;
&lt;p&gt;
Jeg har noen planer for noen Rails-plugins også, da spesielt 			
									
												
			&lt;a href=&quot;http://github.com/cjohansen/validatious-on-rails/tree/master&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;validatious_on_rails&lt;/a&gt;, som søker å automatisere klientsidevalidering fra valideringer satt i ActiveRecord-modellklasser. Dette gjorde jeg litt på i november, og det er vil fungere, jeg må bare gjøre det ferdig. Jeg har også et par andre plugins opp i erme, jeg mangler bare noen timer i døgnet...
&lt;/p&gt;

&lt;p&gt;
En del kodeprosjekter på gang altså, men litt blogging vil jeg også prøve å få tid til.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17975_4&quot;&gt;cjohansen.no i 2009&lt;/h2&gt;
&lt;p&gt;
For det første: jeg skal fjerne julepynten snart, lover! :)
&lt;/p&gt;

&lt;p&gt;
Det er 2 år siden jeg startet å blogge fast nå, og jeg liker det veldig godt. Så godt at jeg har litt lyst til å prøve å nå flere med skribleriene mine. Av den grunnen ønsker jeg å teste å skrive litt på engelsk. Dette vil jeg veldig gjerne ha innspill fra dere som har lest cjohansen.no over en lengre eller kortere periode på. Er det dumt å bytte til engelsk? Har bloggen mye verdi i kraft av å være norsk, eller i kraft av innholdet?
&lt;/p&gt;

&lt;p&gt;
Jeg har ingen umiddelbare planer om å fullstendig legge ned norsk aktivitet, men det er enkelte ting, særlig det som dreier seg om open source-kode jeg skriver, som jeg ønsker å presentere på engelsk for at det skal bli tilgjengelig for flere. Jeg tar som sagt gjerne innspill på dette.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17975_4_1&quot;&gt;Temaer&lt;/h3&gt;
&lt;p&gt;
I nær fremtid håper jeg å få skrevet litt om:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Flash-inkludering med standarder og JavaScript&lt;/li&gt;

&lt;li&gt;mod_rails/phusion passenger + git + capistrano&lt;/li&gt;

&lt;li&gt;mer om JavaScript-testing (blant annet oversette noe fra kalenderen til engelsk)&lt;/li&gt;

&lt;li&gt;og mer&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Jeg håper og tror 2009 blir et spennende år, hva tror dere? Og ikke minst - hva er deres planer for 2009?
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>24 Dec 2008 00:18:07 GMT</pubDate>
  <title>JavaScript-lesestoff</title>
  <link>http://www.cjohansen.no/javascript/javascript_lesestoff</link>
  <guid>http://www.cjohansen.no/javascript/javascript_lesestoff</guid>
  <comments>http://www.cjohansen.no/javascript/javascript_lesestoff#comments</comments>
  <description>
    
&lt;p&gt;
Med litt flaks så har min julekalender dedikert til JavaScripts magiske verden trigget interessen såppass hos noen av dere er sugne på mer grundig stoff om temaet. Her er noen gode bøker og online-ressurser.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17146_1&quot;&gt;Bøker&lt;/h2&gt;
&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/javascript_the_definitive_guide/17154-1-nor-NO/javascript_the_definitive_guide_cover_small.jpg&quot; width=&quot;100&quot; height=&quot;132&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h3 id=&quot;toc17146_1_1&quot;&gt;JavaScript: The Definitive Guide&lt;/h3&gt;
&lt;p&gt;
David Flanagans murstein på O'Reilly er fortsatt den beste fullstendige referansen til språket som jeg har sett. Jeg har ikke lest femteutgaven som er relativt ny, og den skal visstnok være ganske mye omarbeidet. Men, jeg tror jeg kan gå god for den alikevel, de foregående utgavene har ihvertfall vært solide, og jeg har lest Flanagans O'Reilly om Ruby også, og den er også solid. Flanagan står for meg som en fyr du kan stole på ;)
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://oreilly.com/catalog/9780596101992/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;JavaScript: The Definitive Guide, fith edition&lt;/a&gt;
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/javascript_the_good_parts/17166-1-nor-NO/javascript_the_good_parts_cover_small.jpg&quot; width=&quot;100&quot; height=&quot;131&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h3 id=&quot;toc17146_1_2&quot;&gt;JavaScript: The Good Parts&lt;/h3&gt;
&lt;p&gt;
Jeg har skrevet om Douglas Crockfords 			
									&lt;a href=&quot;/JavaScript/JavaScript_the_good_parts&quot;&gt;glimrende bok&lt;/a&gt; tidligere. The Good Parts er en tynn bok med høyt tempo. Den dekker et subsett av språket som Crockford mener er det som utgjør den brukbare delen av JavaScript. Boka er godt skrevet, men er ikke for nybegynnere. Bør leses!
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://oreilly.com/catalog/9780596517748/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;JavaScript: The Good Parts&lt;/a&gt;
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/pro_javascript_design_patterns/17160-1-nor-NO/pro_javascript_design_patterns_cover_small.jpg&quot; width=&quot;100&quot; height=&quot;133&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h3 id=&quot;toc17146_1_3&quot;&gt;Pro JavaScript Design Patterns&lt;/h3&gt;
&lt;p&gt;
Denne boka har fullt fokus på objektorientert JavaScript. Boka starter med en grundig gjennomgang av forskjellige måter å gjøre objektorientering på i JavaScript, implementerer et opplegg for interfaces, og kjører så gjennom et utvalg design patterns. Boka er full med gode, praktiske eksempler og viser veldig godt hvordan JavaScript kan brukes til å implementere &amp;quot;ordentlige&amp;quot; løsninger - mer enn simple ad hoc-løsninger.
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://www.apress.com/book/view/159059908x&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Pro JavaScript Design Patterns&lt;/a&gt;
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/ppk_on_javascript/17157-1-nor-NO/ppk_on_javascript_cover_small.jpg&quot; width=&quot;100&quot; height=&quot;124&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h3 id=&quot;toc17146_1_4&quot;&gt;PPK on JavaScript&lt;/h3&gt;
&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://www.quirksmode.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;PPK - Peter Paul Koch&lt;/a&gt; har lenge vært så å si JavaScripts gudfar (en rolle som kanskje nå utfordres av John Resig??) og skrev i 2006 en relativt tykk bok om JavaScript. Jeg har faktisk ikke lest denne, men utifra innholdsfortegnelsen ser den ut til å operere i samme landskap som Flanagan sin. Hvis noen har vært igjennom denne hører jeg gjerne fra dere!
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://www.quirksmode.org/book/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;PPK on JavaScript&lt;/a&gt;
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/pro_javascript_techniques/17163-1-nor-NO/pro_javascript_techniques_cover_small.jpg&quot; width=&quot;100&quot; height=&quot;132&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h3 id=&quot;toc17146_1_5&quot;&gt;Pro JavaScript Techniques&lt;/h3&gt;
&lt;p&gt;
John Resig, mannen bak jQuery, og kanskje nåtidens største &amp;quot;JavaScript-kjendis&amp;quot; står bak denne boka. Boka dekker objektorientert JavaScript og mange vanlige nettleserproblemer. Boka er langt mer oppgavefokusert enn Flanagans sin, og er langt mer spisset. Boka har så å si ikke noe stoff om jQuery, men dekker alikevel de fleste teknikkene John Resig benyttet da han skrev jQuery. En interessant bok med masse kode som kan tas i bruk som den er (for de som ikke alltid bruker rammeverk).
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://jspro.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Pro JavaScript Techniques&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Andre gode bøker på JavaScript der ute som jeg burde få med meg?
&lt;/p&gt;
	&lt;h2 id=&quot;toc17146_2&quot;&gt;Nettressurser&lt;/h2&gt;
&lt;p&gt;
Det finnes mange, mange ressurser på JavaScript på nettet. Jeg nøyer meg med å nevne to blogger som jeg følger jevnlig med på og oppfordrer dere som leser dette til å tipse om deres egne:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;			
									
												
			&lt;a href=&quot;http://www.quirksmode.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;quirksmode.org&lt;/a&gt; - PPK, nettets beste kilde til inngående informasjon om bugs, og støtte på tvers av nettlesere&lt;/li&gt;

&lt;li&gt;			
									
												
			&lt;a href=&quot;http://ejohn.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;John Resigs blogg&lt;/a&gt; - masse spennende stoff om moderne JavaScript&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Og med det var årets julekalender på cjohansen.no over. God jul allesammen, og takk til alle som har hengt med og lest mine daglige skriblerier!
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>23 Dec 2008 00:22:44 GMT</pubDate>
  <title>JavaScript-organisering, del 2</title>
  <link>http://www.cjohansen.no/javascript/javascript_organisering_del_2</link>
  <guid>http://www.cjohansen.no/javascript/javascript_organisering_del_2</guid>
  <comments>http://www.cjohansen.no/javascript/javascript_organisering_del_2#comments</comments>
  <description>
    
&lt;p&gt;
Igår så vi på noen utfordringer JavaScript-utviklere møter når de føler behovet for å strukturere koden sin på en oversiktelig måte. Idag presenterer jeg noen forslag til løsning på disse utfordringene.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17760_1&quot;&gt;Ytelse: antall script og filstørrelse&lt;/h2&gt;
&lt;p&gt;
De to tingene som påvirker ytelsen for sluttbrukeren er antall filer, og størrelsen på dem. Begge disse er viktige, men antall filer kan fort bli et større problem enn store filer, av to grunner:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Å starte nye http-koblinger er &amp;quot;dyrt&amp;quot;&lt;/li&gt;

&lt;li&gt;Nettlesere flest (per idag) laster ned script sekvensielt, ikke i parallell&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Det siste punktet betyr at dersom du har et 100kB script inkludert før et stilark så vil nettleseren ikke så mye som sniffe på stilarket (eller annen kode som følger scriptet) før hele scriptet er på plass. Dette er også grunnen til at det er anbefalt å laste inn scriptene så sent på siden som mulig.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_1_1&quot;&gt;Filstørrelse&lt;/h3&gt;
&lt;p&gt;
Filstørrelsen er et smalt problem; bruk 				&lt;code&gt;gzip&lt;/code&gt; og minifiser koden. Dette er tema som jeg har 			
									&lt;a href=&quot;/javascript/bedre_ytelse_i_grensenitt&quot;&gt;skrevet om tidligere&lt;/a&gt;. Selv bruker jeg stort sett alltid 			
									
												
			&lt;a href=&quot;http://www.julienlecomte.net/yuicompressor/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;YUI Compressor&lt;/a&gt;, som i de fleste målinger går for å produsere de minste filene. Den fungerer også på CSS-filer.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_1_2&quot;&gt;Antall filer&lt;/h3&gt;
&lt;p&gt;
Antall filer kan minimeres på to måter: enten ved å slå flere filer sammen til én/færre, eller ved å dynamisk laste inn script etter at siden har rendret ferdig. La oss se på disse to løsningene i tur.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_1_3&quot;&gt;Slå sammen filer&lt;/h3&gt;
&lt;p&gt;
I går pratet jeg varmt om å dele opp koden i flere filer, så hvordan kan jeg nå anbefale å slå de sammen igjen? Vel, jeg tenker selvfølgelig på å slå dem sammen igjen som en del av prodsettingsprosessen. Her finnes det mange verktøy du kan få hjelp av. Et 			
											
			&lt;a href=&quot;http://www.google.no/search?hl=no&amp;amp;q=asset+packer&amp;amp;btnG=Google-s%C3%B8k&amp;amp;meta=&amp;amp;aq=f&amp;amp;o&quot; hreflang=&quot;en&quot;&gt;søk i Google etter &amp;quot;asset packer&amp;quot;&lt;/a&gt; gir noen resultater, både for PHP, Ruby og andre.
&lt;/p&gt;

&lt;p&gt;
Felles for alle løsningene jeg har sett er at de krever en form for konfigurering. Det syns jeg er brysomt, så jeg har begynt å kode min egen løsning, som jeg tenkte å presentere kort her.
&lt;/p&gt;

&lt;p&gt;
			
									
												
			&lt;a href=&quot;http://github.com/cjohansen/juicer/tree/master&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Juicer&lt;/a&gt; er et prosjekt jeg har hatt i magen siden januar eller noe, men som av diverse grunner har blitt lagt til side flere ganger. Juicer skiller seg fra andre løsninger på flere måter:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Den er et kommandolinjeverktøy, og er ikke primært tenkt til å bygge små filer &amp;quot;live&amp;quot;&lt;/li&gt;

&lt;li&gt;Den kan slå sammen &lt;b&gt;og&lt;/b&gt; minifisere filer i én og samme operasjon (ved hjelp av YUI Compressor)&lt;/li&gt;

&lt;li&gt;Den krever ingen egen konfigurasjonsfil, kun enkle annoteringer&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
&lt;i&gt;Juicer&lt;/i&gt; fungerer både for CSS og JavaScript. For CSS er det bare å kjøre 
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bat&quot;&gt;juicer merge minfil.css minfil2.css&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
(altså én eller flere filer) og &lt;i&gt;Juicer&lt;/i&gt; vil slå sammen de to filene samt alle filene som er inkludert via 				&lt;code&gt;@import&lt;/code&gt; i de to filene i den nye minifiserte fila minfil.min.css.
&lt;/p&gt;

&lt;p&gt;
I JavaScript finnes det som vi har sett ikke noe verktøy for å importere filer ala CSS' 				&lt;code&gt;@import&lt;/code&gt;. &lt;i&gt;Juicer&lt;/i&gt; leter derfor heller etter den lignende 				&lt;code&gt;@depends &amp;lt;filnavn&amp;gt;&lt;/code&gt; i kommentarer:
&lt;/p&gt;
	&lt;h4 id=&quot;toc17760_1_3_1&quot;&gt;menu.js&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;/**
 * Fancy interactive menu component
 *
 * @depends lib.js
 */
window.MyApp.Menu = {
    // ...
};&lt;/code&gt;&lt;/pre&gt;
	&lt;h4 id=&quot;toc17760_1_3_2&quot;&gt;lib.js&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;/**
 * MyApps library stuff.
 *
 * @depends ../lib/jquery.js
 */
window.MyApp = {
    // ...
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Gitt disse filene vil følgende kommando:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bat&quot;&gt;juicer merge menu.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
produsere den nye filen &lt;i&gt;menu.min.js&lt;/i&gt; som inneholder (i rekkefølge) &lt;i&gt;../lib/jquery.js&lt;/i&gt;, &lt;i&gt;lib.js&lt;/i&gt; og &lt;i&gt;menu.js&lt;/i&gt;. Filen vil også være minifisert av YUI Compressor.
&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;Juicer&lt;/i&gt; er på et veldig tidlig stadie, men jeg tror det kan bli et nyttig verktøy. Hvis du har lyst til å prøve kan du installere via RubyGems (det kommer Ruby-uavhengig versjon når prosjektet modnes mer). Prosjektet er ikke &amp;quot;sluppet&amp;quot; på noe vis enda, så enn så lenge må du hente gem-en fra meg: 			
									&lt;a href=&quot;http://www.cjohansen.no/juicer-0.1.0.gem&quot;&gt;juicer-0.1.0.gem&lt;/a&gt; og installere med
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bat&quot;&gt;gem install juicer-0.1.0.gem&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
som krever på Ruby og RubyGems. Pass også på å følge opp de 			
									&lt;a href=&quot;http://github.com/cjohansen/juicer/tree/master/Readme.rdoc&quot;&gt;ekstra skrittene beskrevet i Readme-en&lt;/a&gt;, sånn at &lt;i&gt;Juicer&lt;/i&gt; finner YUI Compressor.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_1_4&quot;&gt;Dynamisk laste inn script senere&lt;/h3&gt;
&lt;p&gt;
En annen løsning på problemet er å implementere selv det som JavaScript mangler: lazy loading av script. Lazy loading av script går ut på at du først laster inn en kjerne av nødvendige verktøy og deretter bruker en algoritme i denne kjernen til å få nettleseren til å laste ned ytterligere script etterhvert som du trenger det. Dette foregår i bakgrunnen, og brukeren vil ikke merke det med mindre de plutselig kommer &amp;quot;for sent&amp;quot;.
&lt;/p&gt;

&lt;p&gt;
Den enkleste måten å gjøre dette på er at dynamisk bygge et nytt 				&lt;code&gt;script&lt;/code&gt;-element med 				&lt;code&gt;document.createElement&lt;/code&gt; for så å legge det til i 				&lt;code&gt;head&lt;/code&gt;. Utfordringen ligger i å vite når scriptet er ferdig lastet, og her er det flere strategier, men de fleste bibliotekene som gjør dette tilbyr et callback til funksjonen som laster scriptet, altså noe ala:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;load(&amp;quot;min/fil.js&amp;quot;, function() {
    // Bruk funksjonalitet i min/fil.js
});&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;

&lt;li&gt;			
											
			&lt;a href=&quot;http://unixpapa.com/js/dyna.html&quot; hreflang=&quot;en&quot;&gt;En diskusjon rundt utfordringene&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;			
											
			&lt;a href=&quot;http://wonko.com/post/painless_javascript_lazy_loading_with_lazyload&quot; hreflang=&quot;en&quot;&gt;Et (lite) bibliotek som løser utfordringene&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;			
											
			&lt;a href=&quot;http://ajaxpatterns.org/On-Demand_Javascript&quot; hreflang=&quot;en&quot;&gt;Bakgrunnsstoff&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
YUI3 som er rett rundt hjørnet gjør utstrakt bruk av dette på følgende måte:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;YUI().use('node', 'event', 'io', function(Y) {
    // Y er nå YUI-objektet med ønsket funksjonalitet bygget inn
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Selvom du laster inn scriptene asynkront etter at siden er lastet er det viktig å se til at du kun serverer minifiserte filer (for å kutte nedlastingstid), og at disse fortsatt blir skikkelig cachet (for virkelig god ytelse).
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_1_5&quot;&gt;Slå sammen, eller laste seint?&lt;/h3&gt;
&lt;p&gt;
Så, hvilken av disse to skal man gå for? Mitt svar er at &lt;b&gt;det kommer an på&lt;/b&gt;.
&lt;/p&gt;

&lt;p&gt;
Ved å slå sammen og servere alt i én fil kan den inisielle nedlastingsmengden bli veldig stor. Dette betyr at når brukeren kommer til nettstedet ditt med tom cache kan ting lugge litt. Dette kan du også jobbe rundt ved å slå sammen til &lt;i&gt;et fåtall filer&lt;/i&gt;, fremfor bare én. Deretter kan du anstrenge deg for å laste inn så lite som mulig på vanlige innganger (som feks forsiden), for så å servere resten når brukeren allerede har et grunnlag.
&lt;/p&gt;

&lt;p&gt;
Ved å slå sammen til én eller et fåtall filer trenger du ikke bekymre deg for hvorvidt kode du ønsker å bruke er tilgjengelig. Ei heller trenger du å tenke på at du ikke må laste samme fil flere ganger og lignende problemstillinger. Å laste alt er en enklere løsning for deg som utvikler.
&lt;/p&gt;

&lt;p&gt;
Hvorvidt det er akseptabelt å laste alt i en (eller et fåtall) sjau(er) kommer an på:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Hvor mye kode du sender ut&lt;/li&gt;

&lt;li&gt;Hvor hyppig kodebasen brukes&lt;/li&gt;

&lt;li&gt;Hva som er viktigst: første sidevisning er svinkjapp, eller f.eks et knappetrykk reagerer umiddelbart&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Dersom du sender ut veldig mye kode er det kanskje bedre å laste inn filene asynkront for å spre arbeidsmengden.
&lt;/p&gt;

&lt;p&gt;
Dersom du har mye kode som brukes sjelden er det dårlig gjort å be brukeren laste ned alt i en jafs.
&lt;/p&gt;

&lt;p&gt;
Dersom du laster kode asynkront er det en viss sjans for at brukeren må vente f.eks første gang hun trykker på en knapp fordi nettleseren må laste ned scriptet som skal kjøres for denne knappen. Laster du inn scriptene asynkront bør du passe på at enkeltfilene ikke er for store.
&lt;/p&gt;

&lt;p&gt;
Det er mange ting å tenke på her, og midt oppe i det hele kommer det jo elementet av hva utvikleren(e) som koder på systemet foretrekker. Også bør man huske at når man serverer all koden er det bare ved tom cache at brukeren på vente. Laster du inn scriptene som det siste du gjør på siden vil også brukeren ha hele siden tilgjengelig mens scriptet laster, så det er ikke aktiv venting det er snakk om.
&lt;/p&gt;

&lt;p&gt;
Med andre ord: &amp;quot;&lt;i&gt;it depends&lt;/i&gt;&amp;quot;.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17760_2&quot;&gt;Innlede kode&lt;/h2&gt;
&lt;p&gt;
Når vi koder ikke-påtrengende JavaScript er alle event handlerne borte fra HTML-en vår. Dette betyr at vi trenger kode som legger til disse dynamisk. Igår nevnte jeg noen måter å gjøre dette på:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Én global 				&lt;code&gt;DOMContentLoaded&lt;/code&gt;-handler som kjører igang alt&lt;/li&gt;

&lt;li&gt;Én 				&lt;code&gt;DOMContentLoaded&lt;/code&gt;-handler per fil/komponent som &amp;quot;starter seg selv&amp;quot;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Vi så hvordan begge disse hadde både fordeler og ulemper. Heldigvis lar det seg løse. Ved å lene oss på konvensjoner kan vi kjøre all start-kode fra ett sentralt sted, men flytte komponent-spesifik kode til hver enkelt komponent.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17760_2_1&quot;&gt;Autoload&lt;/h3&gt;
&lt;p&gt;
Jeg har den senere tiden prøvd et enkelt autoload-konsept. Hver &amp;quot;klasse&amp;quot; som har business idet siden laster definerer en 				&lt;code&gt;autoload&lt;/code&gt;-metode som tar imot et 				&lt;code&gt;options&lt;/code&gt;-objekt. Denne metoden inneholder relativt generisk oppstartskode, som blir sidespesifik i kraft av innsendte 				&lt;code&gt;options&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Sentralt har jeg et lite stykke kode (vist under) som looper navnerommet for applikasjonen og finner alle &amp;quot;klasser&amp;quot; som definerer en 				&lt;code&gt;autoload&lt;/code&gt;, og kjører disse:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;/**
 * Fire up autoloaded objects when document is loaded.
 *
 * @depends mootools.js
 */
window.addEvent('domready', function() {
    var component, args;

    // Loop all namespaces directly under myApp namespace
    for (var object in myApp) if (myApp.hasOwnProperty(object)) {
        component = myApp[object];

        // Check that the component defines autoload
        if (!(typeof myApp.autoload === &amp;quot;function&amp;quot;)) {
            continue;
        }

        // Look for arguments in myApp.autoload
        args = $defined(myApp.autoload[object]) ? myApp.autoload[object] : null;

        // Fire autoload
        $debug(&amp;quot;Autoloading &amp;quot; + object);
        component.autoload(args);
    }
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Enn så lenge er det ikke noe sidespesifik kode som kjøres. Men så kommer trikset da. I tillegg til denne koden har jeg et objekt som inneholder verdier for 				&lt;code&gt;options&lt;/code&gt; for enkelte komponenter:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;// Namespace for configuring autoloaded modules
myApp.autoload = {
    ModuleName: { options: &amp;quot;object&amp;quot; },
    OtherModule: {},
    // ...
};&lt;/code&gt;&lt;/pre&gt;
	&lt;h4 id=&quot;toc17760_2_1_1&quot;&gt;Et praktisk eksempel&lt;/h4&gt;
&lt;p&gt;
Jeg har i et aktuelt prosjekt eksempelvis en dropdownmeny. For å øke brukbarheten i den er den ikke gjort med 				&lt;code&gt;:hover&lt;/code&gt; (CSS), men heller med JavaScript for å kunne implementere litt delay på mouseout osv. Denne komponenten ser ut som følger:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;/**
 * Dropdown menu component. Takes a ul/ol element as argument and turns it into
 * an interactive dropdown menu. Every li directly under the list that contains
 * a ul/ol element as direct child will act as a drop down when it gets focus
 * (ie mouseover and focus from keyboard).
 *
 * @params list The list element
 */
myApp.Menu = (function() {
    // Implementation...
})();

/**
 * Autoload menu. Options are
 *
 * menuList - The ul or ol element that is the root of the menu
 *
 * @param {Object} options
 */
myApp.Menu.autoload = function(options) {
    if (options &amp;amp;&amp;amp; options.menuList) {
        new myApp.Menu(options.menuList);
    }
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Autoload-koden er som vist over, og konfigureringsobjektet ser nå ut som:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;myApp.autoload = {
    // Add dropdown functionality to menu (defined in widgets/menu.js)
    Menu: { menuList: $$('#nav ul')[0] }
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Hva har jeg oppnådd med dette?
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Menykomponenten er helt generisk og kan verbatim gjenbrukes i andre prosjekter&lt;/li&gt;

&lt;li&gt;Menykomponenten kommuniserer til meg at den lastes ved sidevisning fordi den har en 				&lt;code&gt;autoload&lt;/code&gt;-metode&lt;/li&gt;

&lt;li&gt;Koden som faktisk kjører idet siden lastes finnes kun ett sted - i autoload.js&lt;/li&gt;

&lt;li&gt;De sidespesifikke verdiene (som hvilket element som er dropdown-menyen min) er samlet i en lettlest &amp;quot;config-fil&amp;quot; (config.js)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Med andre ord er ting godt separert samtidig som de ved hjelp av noen konvensjoner henger sammen på en (forhåpentligvis) tydelig måte.
&lt;/p&gt;

&lt;p&gt;
Det var noen rutiner for strukturering som jeg holder meg til. Jeg regner med at dere andre sitter på deres egne, og jeg er veldig interessert i å høre hvordan disse fungerer, og hva dere syns om opplegget jeg her har presentert.
&lt;/p&gt;

&lt;p&gt;
I morgen er det årets siste &amp;quot;luke&amp;quot; i kalenderen, vel møtt!
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>22 Dec 2008 00:02:09 GMT</pubDate>
  <title>Å organisere større JavaScript-prosjekter</title>
  <link>http://www.cjohansen.no/javascript/aa_organisere_stoerre_javascript_prosjekter</link>
  <guid>http://www.cjohansen.no/javascript/aa_organisere_stoerre_javascript_prosjekter</guid>
  <comments>http://www.cjohansen.no/javascript/aa_organisere_stoerre_javascript_prosjekter#comments</comments>
  <description>
    
&lt;p&gt;
Når mengden JavaScript stadig øker blir det hele tiden viktigere å organisere koden på et vis. Gjennom to artikler skal vi se hvordan vi kan oppnå kode som både er lettere å vedlikeholde og å jobbe flere sammen på.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17136_1&quot;&gt;Livet i ad hoc-verden&lt;/h2&gt;
&lt;p&gt;
JavaScript har tradisjonelt sett blitt utviklet på en ad hoc-aktig måte. Jeg tror følgende er beskrivende for mye kode som finnes der ute:
&lt;/p&gt;

&lt;p&gt;
Man bygger en webside, og får på et tidspunkt behov for å krydre opp interaksjonen med litt JavaScript. Kanskje noen linker som skal sende inn et skjema, litt enkel skjemavalidering og et par Ajax-dingser.
&lt;/p&gt;

&lt;p&gt;
Noen funksjoner blir rablet ned, stappet i 				&lt;code&gt;&amp;lt;head/&amp;gt;&lt;/code&gt;, og disse aksesseres fra noen inline eventhandlere. Etterhvert blir det mer, og man flytter litt kode ut i en egen scriptfil. På sikt blir denne stor, og man deler kanskje opp i to filer: generiske komponenter i &lt;i&gt;lib.js&lt;/i&gt; og noe mer site-spesifikk kode i &lt;i&gt;site.js&lt;/i&gt; eller lignende.
&lt;/p&gt;

&lt;p&gt;
Langs veien kommer det til et js-rammeverk, og noen slipper inn litt autogenerert kode fra serverside-rammeverket og ting begynner å vokse ut av proporsjoner. To utviklere som jobber på hver sin &amp;quot;lib&amp;quot;-komponent må merge endringene hver gang de commiter fordi begge komponentene er i samme fil.
&lt;/p&gt;

&lt;p&gt;
Und so weiter. Denne strategien kommer &lt;b&gt;fort&lt;/b&gt; til kort. Ikke minst gir den et lite intuitivt miljø for nye utviklere å tre inn i.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_2&quot;&gt;JavaScripts mangler&lt;/h2&gt;
&lt;p&gt;
Noe av skylda for at man ender opp med slike lite intuitive oppsett &lt;i&gt;kan&lt;/i&gt; man tillegge JavaScript. JavaScript tilbyr ingen verktøy for å strukturere koden din. Her er det ikke noe pakkesystem ala Javas, ikke noe 				&lt;code&gt;require&lt;/code&gt; eller 				&lt;code&gt;import&lt;/code&gt;. JavaScript har - som vi tidligere har sett - ikke engang et opplegg for navnerom - all kode evalueres i det globale miljøet.
&lt;/p&gt;

&lt;p&gt;
Det eneste JavaScript byr oss på av verktøy er 				&lt;code&gt;&amp;lt;script/&amp;gt;&lt;/code&gt; (...) og fleksible objekter. It ain't much, men det er nok til at vi med litt disiplin kan organisere oss på en skikkelig måte.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_3&quot;&gt;Mål&lt;/h2&gt;
&lt;p&gt;
Det er greit å ha en formening om hva vi ønsker å oppnå. Her er forslag til noen mål med koden vår:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Kode skal være oversiktlig og lett å orientere seg i - både for nye og gamle utviklere&lt;/li&gt;

&lt;li&gt;Komponenter bør være løst koplet, og enkelt å skru av enkeltvise komponenter&lt;/li&gt;

&lt;li&gt;Koden bør legge til rette for at flere utviklere kan jobbe sammen på den&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
I resten av artikkelen, og i morgen, skal jeg forsøke å lansere &lt;b&gt;ett forslag til løsning&lt;/b&gt;. Siden det ikke er noen &amp;quot;den ene JavaScript-måten&amp;quot; å gjøre dette på så blir mitt forslag bare, vel, et forslag. Det er sikkert mange andre praksiser der ute som fungerer fint, og jeg hører gjerne fra dere som leser hvordan dere løser organisering av kode.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_4&quot;&gt;Forutsetninger&lt;/h2&gt;
&lt;p&gt;
Jeg forutsetter i mitt forslag at man jobber på et prosjekt hvor det er mer enn minimalt med JavaScript. Hva som definerer en slik minimumsmengde er vanskelig å si. Men jeg har altså ikke de helt minste prosjektene i tankene her. I tillegg forutsetter jeg en hang til objektorientert design. Det er helt mulig å skrive funksjonsorientert JavaScript bra, men for nå fokuserer jeg altså på en objektorientert tilnærming.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_5&quot;&gt;Globalt skop og navnerom&lt;/h2&gt;
&lt;p&gt;
Jeg har tidligere i kalenderen gått gjennom en måte å løse problematikken rundt det globale skopet på. Hvorvidt du bruker 				&lt;code&gt;namespace()&lt;/code&gt;-metoden fra tidligere, noe lignende, eller rett og slett bare manuelt håndterer objektene er hipp som happ. Fordelen med å bruke noe ala 				&lt;code&gt;namespace()&lt;/code&gt; er at man får litt løsere kopling mellom komponentene.
&lt;/p&gt;

&lt;p&gt;
				&lt;code&gt;namespace()&lt;/code&gt; gir deg et objekt uansett om objekter i &amp;quot;stien&amp;quot; er definert eller ikke, og dette gjør at man ikke trenger å stokke filer i en forhåndsdefinert rekkefølge for å få navnerommene til å laste riktig. Sålenge objektene da ikke på andre måter avhenger av hverandre står man litt friere i forhold til rekkefølge.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_6&quot;&gt;Objekter og filer&lt;/h2&gt;
&lt;p&gt;
Vi deler altså koden vår opp i logiske komponenter. Disse komponentene kan for enkle tilfeller bli enkeltobjekter (&amp;quot;klasser&amp;quot;), eller for mer sammensatte tilfeller bli en gruppe objekter (&amp;quot;klasser&amp;quot;). Her kan man enten skjære helt igjennom og gjøre som man gjør i Java: hver komponent/&amp;quot;klasse&amp;quot; i hver sin fil. Eller, man kan tillate å samle flere enn en &amp;quot;klasse&amp;quot; i én fil når disse sammen er en feature, eller er i samme navnerom. Litt skjønn kan man utvise.
&lt;/p&gt;

&lt;p&gt;
Hensikten med denne oppdelingen er selvfølgelig å få bedre oversikt over koden, og å skille enkeltdelene bedre. Med et oppsett som dette er det også langt lettere å skru av enkeltfunksjonalitet skulle det være aktuelt.
&lt;/p&gt;

&lt;p&gt;
Nettopp fordi oversikt og utviklervennlige filer er et viktig poeng er det greit å utøve skjønn i forhold til hvordan man deler kode opp i filer. Mange filer med småobjekter på 10-20 linjer &lt;i&gt;kan&lt;/i&gt; bidra til mer rot enn oversikt. Her må teamet bli enige om hva som passer utviklerne best.
&lt;/p&gt;

&lt;p&gt;
Dette er vel og bra, hadde det bare ikke vært for at JavaScript ikke har noen enkel måte å inkludere et script fra et annet script på, &lt;b&gt;og&lt;/b&gt; at flere filer alltid betyr dårligere ytelse. Dette problemet takler vi først i morgendagens artikkel.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17136_7&quot;&gt;Hvordan kjøre ikke-påtrengende kode?&lt;/h2&gt;
&lt;p&gt;
Når vi skriver ikke-påtrengende JavaScript får vi mange fordeler, men også noen nye utfordringer. Den mest åpenbare går på at vi nå trenger et nytt &amp;quot;lag&amp;quot; der det settes eventhandlere på elementer, og forskjellige script-elementer settes opp. Fordi vi ikke ønsker forsinkelse i denne fasen (det vil resultere i flikking og andre uønskede effekter) så gjøres dette gjerne på den raskeste måten: gjennom en implementasjon av 				&lt;code&gt;DOMContentLoaded&lt;/code&gt;-eventen.
&lt;/p&gt;

&lt;p&gt;
Å vite hvordan vi skal hekte på funksjonaliteten er greit nok - men det er ihvertfall to måter å gjøre det på:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;En eventhandler for 				&lt;code&gt;DOMContentLoaded&lt;/code&gt; i hver enkelt fil som inisierer komponenten&lt;/li&gt;

&lt;li&gt;En eventhandler i en fil som &amp;quot;starter&amp;quot; alle komponentene&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
Den første løsningen har en ulempe i at den kobler sidespesifik funksjonalitet med våre (forhåpentligvis) godt abstraherte komponenter. Dessuten sprer den &amp;quot;bootup&amp;quot;-logikk rundt i mange filer.
&lt;/p&gt;

&lt;p&gt;
Den andre løsningen har en ulempe i at den skiller logikken bak en komponent fra logikken for å kjøre den i forskjellige filer. Derimot har den en styrke i at det blir en lett tilgjengelig plass å finne ut av hva som kjøres når siden lastes.
&lt;/p&gt;

&lt;p&gt;
Noen praktiske løsninger på disse utfordringene, samt noen forslag til løsning på problemer med mange js-filer ser vi på i morgendagens noe mer praktisk orienterte artikkel. Vel møtt!
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>21 Dec 2008 22:19:57 GMT</pubDate>
  <title>Debugging og profilering av JavaScript</title>
  <link>http://www.cjohansen.no/javascript/debugging_og_profilering_av_javascript</link>
  <guid>http://www.cjohansen.no/javascript/debugging_og_profilering_av_javascript</guid>
  <comments>http://www.cjohansen.no/javascript/debugging_og_profilering_av_javascript#comments</comments>
  <description>
    
&lt;p&gt;
Firebug er et uvurderlig verktøy for JavaScript-utvikling (og mer). Her ser vi på noen av de nyttigste verktøyene Firebug stiller opp med: debugging, profilering og inspeksjon.
&lt;/p&gt;

    
&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/firebug_konsoll/17172-1-nor-NO/firebug_konsoll_article.png&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h2 id=&quot;toc17126_1&quot;&gt;Konsollet&lt;/h2&gt;
&lt;p&gt;
Når du åpner Firebug vil den automatisk stå i konsollet. Miljøet i konsollet er å betrakte som et script som ligger inkludert på den aktuelle siden i kraft av at du har tilgang til dokumentet gjennom 				&lt;code&gt;document&lt;/code&gt; og at kode du skriver i konsollet ellers fungerer som den ville gjort inkludert på siden. I tillegg gir konsollet noe tilleggsinformasjon.
&lt;/p&gt;

&lt;p&gt;
Konsollet skriver for eksempel ut verdien av alle uttrykk som kjøres i det. Henter du noen elementer med 				&lt;code&gt;document.getElementsByTagName&lt;/code&gt; så får du umiddelbart tilbakemelding om at dette resulterte i en 				&lt;code&gt;HTMLCollection&lt;/code&gt; osv.
&lt;/p&gt;

&lt;p&gt;
Av og til ønsker man å prøve ut mer enn en linje kode. Dette gjelder for eksempel mange av kodeeksemplene jeg har gitt i kalenderens løp - hvor det ofte er en funksjonsdefinisjon eller to med også. I slike tilfeller kan du klikke på den lille røde pila nederst i høyre hjørne. Da får du et tekstfelt fremfor konsollinja. Her kan du paste inn så mye kode du bare gidder, og så klikke &amp;quot;Run&amp;quot; når du er klar.
&lt;/p&gt;

&lt;p&gt;
Firebug bidrar også med 				&lt;code&gt;$(id)&lt;/code&gt; og 				&lt;code&gt;$$(cssSelector)&lt;/code&gt; dersom du ikke allerede har metoder som dette.
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/firebug_konsoll_logging/17175-1-nor-NO/firebug_konsoll_logging_article.png&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h2 id=&quot;toc17126_2&quot;&gt;Logging til konsollet&lt;/h2&gt;
&lt;p&gt;
Å ha et konsoll der man kan leke seg med JavaScript er absolutt svært verdifullt. Men det stopper ikke der - Firebug kan også logge info fra scriptene dine. Du kan bruke følgende metoder fra hvorsom helst for å debugge applikasjonen din:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;				&lt;code&gt;console.log()&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;console.info()&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;console.warn()&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;console.error()&lt;/code&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Samtlige av disse tar en tekst og valgfritt en mengde parametere. Parameterne kan brukes sammen med 				&lt;code&gt;sprintf&lt;/code&gt;-type strenger:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;// I et script på siden
var h1 = document.getElementsByTagName(&amp;quot;h1&amp;quot;)[0];
console.info(&amp;quot;h1 is %s&amp;quot;, h1);

if (h1.innerHTML !== &amp;quot;Hey!&amp;quot;) {
    console.warn(&amp;quot;h1 text is '%s'&amp;quot;, h1.innerHTML);
    h1.innerHTML = &amp;quot;Hey!&amp;quot;;
}

console.log(h1);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Den siste linja logger selve objektet til konsollet, og det som er litt kult er at vi kan klikke på logbeskjeden i konsollet, og bli ledet rett videre til inspeksjon.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17126_3&quot;&gt;Inspeksjon&lt;/h2&gt;
&lt;p&gt;
Firebug tilbyr et utvalg måter å inspisere koden vår på. Den mest åpenbare er den du finner under &amp;quot;inspect&amp;quot;-menyvalget. Denne gir deg et innblikk i HTML-en. I motsetning til vanlig &amp;quot;view source&amp;quot; er dette innsynet dynamisk, og oppdaterer seg løpende ettersom scriptene dine manipulerer DOM-en. Du kan også klikke på inspect-valget for så å dra musa rundt i webapplikasjonen din for å inspisere et element du ser på skjermen.
&lt;/p&gt;

&lt;p&gt;
En siste måte å bruke HTML-inspectoren på er å kalle funksjonen 				&lt;code&gt;inspect(obj)&lt;/code&gt;. Det gir det samme resultatet, men er en programmatisk inngang til samme funksjonalitet.
&lt;/p&gt;

&lt;p&gt;
I det høyre panelet under inspeksjon er det flere nyttige ting å ta seg til. I utgangspunktet viser dette informasjon hvilke CSS-regler som er i effekt. Dette er i seg selv nyttig for å se hvilke regler som blir gjeldende i enkelttilfeller. Benytter du deg av &amp;quot;Options&amp;quot; oppe til høyre på denne vil du også finne muligheten til å se beregnede verdier for forskjellige CSS-egenskaper.
&lt;/p&gt;

&lt;p&gt;
Neste panel som tilbys her er et layout-panel som visualiserer de av de beregnede CSS-egenskapene som har med boksmodellen å gjøre. Til slutt finner vi et DOM-panel. Dette gir en oversikt over alle egenskaper et gitt objekt har, og kan være svært nyttig både for å kartlegge hva nettleseren tilgjengeliggjør for deg, og for å inspisere verdier.
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/firebug_breakpointer/17169-1-nor-NO/firebug_breakpointer_article.png&quot; width=&quot;533&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h2 id=&quot;toc17126_4&quot;&gt;Debugging&lt;/h2&gt;
&lt;p&gt;
Firebug har også en debugger. Den enkleste måten å debugge et script på er å velge &amp;quot;script&amp;quot;-menyvalget i Firebug. Fra listen av script kan du velge det aktuelle scriptet (html-siden selv dersom scriptet er inline). I kodelistingen som dukker opp kan du rett og slett klikke med musa på linjenummere hvor du ønsker et breakpoint. Høyreklikker du på breakpointet kan du angi en kondisjon smo må tilfredsstilles for at breakpointeren skal stoppe her.
&lt;/p&gt;

&lt;p&gt;
Når du har satt de merkene du ønsker er det bare å enten kalle metoden(e) på nytt via konsollet, eller å laste siden på nytt (for å få kode i onload-eventhandlere til å kjøre). Breakpointene blir værende selvom du laster siden på nytt - for å fjerne dem må du selv aktivt merke dem av. Når du nå kjører koden vil Firebug stoppe ved alle merkene og vise debug informasjon om alle variabler som er i konteksten der koden stoppet.
&lt;/p&gt;

&lt;p&gt;
Du kan også legge inn breakpoints fra koden din: simpelthen legg til 				&lt;code&gt;breakpoint;&lt;/code&gt; der du vil at koden skal stoppe.
&lt;/p&gt;

&lt;p&gt;
I panelet til venstre (når du er inne på &amp;quot;scripts&amp;quot;) kan du også velge &amp;quot;Break on all errors&amp;quot; fra Options. Da vil du få muligheten til å inspisere miljøet der et script slutter å fungere.
&lt;/p&gt;

&lt;div class=&quot;object-right&quot;&gt;&lt;div class=&quot;image right&quot;&gt;
  	
	
	
	
	
	
				&lt;img src=&quot;/var/cj_no/storage/images/media/images/firebug_profiler/17178-1-nor-NO/firebug_profiler_article.png&quot; width=&quot;400&quot; height=&quot;400&quot; alt=&quot;&quot; /&gt;	
	&lt;/div&gt;
&lt;/div&gt;	&lt;h2 id=&quot;toc17126_5&quot;&gt;Profilering&lt;/h2&gt;
&lt;p&gt;
Profilering gir deg informasjon av hvor mye tid hver enkelt bit av koden din bruker. Profileren i Firebug gir også informasjon om hvor stor andel av total tid en gitt metode bruker, noe som kan være svært nyttig når du ønsker å identifisere flaskehalser. Selvom du ikke mistenker trøbbel kan det være greit å kikke litt i profileren en gang i blant bare for å se om det foregår noe unormalt (kode som bruker mye lengre tid enn annen kode osv). Med litt flaks får du servert noen muligheter til optimalisering på et søvlfat.
&lt;/p&gt;

&lt;p&gt;
Den enkleste måten å profilere på er å trykke på &amp;quot;Profile&amp;quot;-menyvalget som du finner i den øverste linja i Firebug (sammen med &amp;quot;Inspect&amp;quot; og &amp;quot;Clear&amp;quot; - menysystemet til Firebug er ikke kjempeintuitivt). Når du har gjort det går profileren i bakgrunnen. Nå kan du kjøre kode eller ha interaksjon med siden som trigger events. Når du har gjort det du ønsker å måle kan du trykke &amp;quot;Profile&amp;quot; igjen, og du får opp en rapport.
&lt;/p&gt;

&lt;p&gt;
Du kan også starte profileren fra kode med 				&lt;code&gt;console.profile(&amp;quot;Label&amp;quot;);&lt;/code&gt; og deretter stoppe den med 				&lt;code&gt;console.profileEnd(&amp;quot;Label&amp;quot;);&lt;/code&gt;. Labelen for de to må være den samme - på denne måten kan du kjøre flere profileringer som ikke nødvendigvis nøster symmetrisk.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17126_6&quot;&gt;Hva med de andre nettleserne?&lt;/h2&gt;
&lt;p&gt;
Vel, Safari har noe Firebug-aktig i sin 			
									&lt;a href=&quot;http://webkit.org/blog/41/&quot;&gt;Web Inspector&lt;/a&gt;. Jeg har ingen erfaring med den og kan ikke egentlig si noe fornuftig om den. Om noen har, del gjerne!
&lt;/p&gt;

&lt;p&gt;
I Opera har det nå kommet noe som heter 			
									
												
			&lt;a href=&quot;http://dev.opera.com/articles/view/introduction-to-opera-dragonfly/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Dragonfly&lt;/a&gt;, som utifra beskrivelsen ser ut til å dekke mesteparten av det Firebug dekker:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;JavaScript debugger&lt;/li&gt;

&lt;li&gt;DOM inspector&lt;/li&gt;

&lt;li&gt;CSS inspector&lt;/li&gt;

&lt;li&gt;Command Line to allow commands to be inputed&lt;/li&gt;

&lt;li&gt;Error Console that outputs validation errors and warnings exhibited by the CSS and JavaScript connected with the page&lt;/li&gt;

&lt;li&gt;Proxy to allow debugging directly on mobile devices&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
Jeg har heller ikke prøvd denne, men del gjerne erfaringer dere som har.
&lt;/p&gt;

&lt;p&gt;
IE-gjengen henger som vanlig etter, men det finnes 			
											
			&lt;a href=&quot;http://blogs.msdn.com/ie/archive/2007/06/22/from-microsoft-teched-2007-web-development-tools-for-internet-explorer.aspx&quot; hreflang=&quot;en&quot;&gt;noen verktøy&lt;/a&gt;. Den viktigste per idag er vel 			
											
			&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkId=92716&quot; hreflang=&quot;en&quot;&gt;IE Developer Toolbar&lt;/a&gt;. MS jobber vel også med noe til IE8, men om det er en utbedret versjon av IE Developer Toolbar eller noe nytt er jeg ikke helt sikker på. For å være ærlig skal det bli en kald dag i helvete før jeg sitter med IE som utviklingsverktøy. &lt;b&gt;Men&lt;/b&gt;, det kan jo være nyttig for å debugge når du får problemer med IE (og det skjer jo stadig vekk).
&lt;/p&gt;
	&lt;h3 id=&quot;toc17126_6_1&quot;&gt;Firebug lite&lt;/h3&gt;
&lt;p&gt;
Min situasjon er sånn at jeg jobber med Firefox som min primære utviklingsnettleser. Jeg tester med Opera, Safari og IE jevnlig for å se til at ting er på stell. Jeg har ikke like store behov for verktøy til alle nettleserne fordi jeg ikke gjør stort utover litt enkel debugging i de fleste av dem. Og til dette fungerer 			
									
												
			&lt;a href=&quot;http://getfirebug.com/lite.html&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Firebug Lite&lt;/a&gt; helt perfekt. Det er som navnet indikerer en lettvektsversjon av Firebug som funker som et vanlig script og kan brukes i IE, Opera og Safari.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen, når vi ser på organisering i middels til store JavaScript-prosjekter.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>20 Dec 2008 20:48:56 GMT</pubDate>
  <title>Mixins og multippel arv i JavaScript</title>
  <link>http://www.cjohansen.no/javascript/mixins_og_multippel_arv_i_javascript</link>
  <guid>http://www.cjohansen.no/javascript/mixins_og_multippel_arv_i_javascript</guid>
  <comments>http://www.cjohansen.no/javascript/mixins_og_multippel_arv_i_javascript#comments</comments>
  <description>
    
&lt;p&gt;
Fordi metoder er helt vanlige egenskaper på objekter er det fullt mulig å dele metoder fritt mellom objekter. På denne måten støtter JavaScript indirekte multippel arv fordi ett objekt kan &amp;quot;arve&amp;quot; oppførsel fra flere enn ett annet objekt.
&lt;/p&gt;

    
&lt;p&gt;
I 			
									&lt;a href=&quot;/javascript/en_nyttigere_document_createelement&quot;&gt;gårsdagens tutorial&lt;/a&gt; (og 			
									&lt;a href=&quot;/javascript/hjelperen&quot;&gt;den første om $()&lt;/a&gt;) har vi sett ett eksempel på hvordan to objekter kan dele på en metode. Vi definerte metoder inn i 				&lt;code&gt;cj.Element&lt;/code&gt; som kunne kalles direkte fra dette navnerommet. Deretter laget vi vår 				&lt;code&gt;extend&lt;/code&gt;-metode som laget en anonym funksjon rundt hver og én av disse metodene for bruk gjennom et elements prototype.
&lt;/p&gt;

&lt;p&gt;
Å legge metoder rundt på denne måten er én måte å dele metoder på, som også tillater deg å endre noe på grensesnittet. I vårt eksempel var det snakk om å unngå element-parameteret (som vi allerede hadde innebygget fra et gitt element).
&lt;/p&gt;

&lt;p&gt;
Noen ganger kan det være interessant å kopiere metoder rett over uten å endre på grensesnittet. I disse tilfellene kan vi rett og slett gjøre:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;String.prototype.isLongerThan = function(len) {
    return this.length &amp;gt; len;
};

console.log(&amp;quot;Hey there&amp;quot;.isLongerThan(3)); // true

Array.prototype.isLongerThan = String.prototype.isLongerThan;

console.log([&amp;quot;Hey&amp;quot;, &amp;quot;there&amp;quot;].isLongerThan(3)); // false&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Her utvider vi først prototypen til strenger med en tullete metode som sjekker om strengen er lengre enn en gitt lengde. Deretter kopierer vi metoden verbatim over i array sin prototype og får umiddelbart samme funksjonalitet på arrayer. Dette fungerer fordi både arrayer og strenger har en 				&lt;code&gt;length&lt;/code&gt;-egenskap.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17116_1&quot;&gt;Mixins&lt;/h2&gt;
&lt;p&gt;
De av dere som har erfaring med Ruby, Python, Perl og diverse andre språk vil sikkert notere seg at vi i eksempelet over touchet innom noe som ligner på 			
									
												
			&lt;a href=&quot;http://en.wikipedia.org/wiki/Mixin&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;mixins&lt;/a&gt;. JavaScript har ikke støtte for Mixins på språknivå, men å få full mixin-støtte er alikevel bare en metode unna. Faktisk kan vi bruke 				&lt;code&gt;extend&lt;/code&gt;-metoden som vi 			
									&lt;a href=&quot;/javascript/funksjoner_og_parametere&quot;&gt;laget tidligere&lt;/a&gt;. Alt den trenger å gjøre er å kopiere egenskaper fra ett objekt til et annet.
&lt;/p&gt;

&lt;p&gt;
Jeg minner om hvordan den fungerer:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var object = { a: 1 };
object = extend(object, { b: 2 });
// object == { a: 1, b: 2 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Det som er kult med mixins er at vi kan gi objekter funksjonalitet uten å tvinge &amp;quot;klassen&amp;quot; til å subklasse andre klasser. Med andre ord kan vi si noe direkte om &lt;b&gt;hva en gruppe objekter kan&lt;/b&gt; fremfor &lt;b&gt;hva de er&lt;/b&gt;.
&lt;/p&gt;

&lt;p&gt;
I Ruby brukes for eksempel mixins til å gi forskjellige objekter et bredt spekter av enumerable-funksjonalitet (norsk ord anyone??). Såfremt en klasse definerer en instansmetode 				&lt;code&gt;each&lt;/code&gt; som gir underelementer én etter en så vil 				&lt;code&gt;Enumerable&lt;/code&gt;-mixinen gi disse objektene andre nyttige metoder så som 			
											
			&lt;a href=&quot;http://ruby-doc.org/core/classes/Enumerable.html#M003162&quot; hreflang=&quot;en&quot;&gt;				&lt;code&gt;all?&lt;/code&gt;&lt;/a&gt;, 			
											
			&lt;a href=&quot;http://ruby-doc.org/core/classes/Enumerable.html#M003164&quot; hreflang=&quot;en&quot;&gt;				&lt;code&gt;min&lt;/code&gt;&lt;/a&gt; og 			
											
			&lt;a href=&quot;http://ruby-doc.org/core/classes/Enumerable.html#M003150&quot; hreflang=&quot;en&quot;&gt;				&lt;code&gt;sort&lt;/code&gt;&lt;/a&gt;. De to siste krever også at enkeltverdiene har definert en sammenligningsmetode.
&lt;/p&gt;

&lt;p&gt;
La oss se et eksempel på dette i JavaScript. Først, la oss se et eksempel på iteratoren, som i JavaScript for arrayer heter 				&lt;code&gt;forEach&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(fun /*, thisp*/) {
        var len = this.length;

        if (typeof fun != &amp;quot;function&amp;quot;)
            throw new TypeError();

        var thisp = arguments[1];

        for (var i = 0; i &amp;lt; len; i++) {
            if (i in this)
                fun.call(thisp, this[i], i, this);
        }
    };
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Dette er 			
											
			&lt;a href=&quot;https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:forEach&quot; hreflang=&quot;en&quot;&gt;Mozillas implementasjon&lt;/a&gt; som vi har sett før. Den kan brukes som så:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var arr = [2, 3, 4, 1];

arr.forEach(function(element) {
    console.log(element);
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
La oss nå lage noen enumerable-metoder som benytter seg av denne iteratoren. Jeg illustrerer som vanlig først bruk med noen tester, så presenterer jeg en implementasjon.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;new Test.Unit.Runner({
    testIsMixedIntoArrays: function() { with(this) {
        var array = [1, 2, 3, 4];
        assertNotUndefined(Array.prototype.all);
        assertNotUndefined(array.all);
    }},

    testAll: function() { with(this) {
        var array = [1, 2, 3, 4];
        assert(!array.all(function(num) { return num &amp;gt; 1; }));
        assert(array.all(function(num) { return num &amp;gt; 0; }));
    }},

    testAny: function() { with(this) {
        var array = [1, 2, 3, 4];
        assert(array.any(function(num) { return num &amp;gt; 1; }));
        assert(array.any(function(num) { return num &amp;gt; 0; }));
        assert(!array.any(function(num) { return num === 0; }));
    }},

    testCollect: function() { with(this) {
        var array = [document.getElementById(&amp;quot;list&amp;quot;), document.getElementById(&amp;quot;something&amp;quot;)];

        assertEnumEqual([&amp;quot;ul&amp;quot;, &amp;quot;div&amp;quot;], array.collect(function(element) {
            return element.tagName.toLowerCase();
        }));
    }}
}, { testLog: &amp;quot;enumerablelog&amp;quot; });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Som forventet 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/mixins/test1.html&quot;&gt;feiler testene&lt;/a&gt;. Så var det implementasjonen.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var cj = {};

cj.Enumerable = {
    // Error type used to abort forEach callbacks
    StopIteration: function() {},

    /**
     * Returns true if the callback never returns a falsy value
     */
    all: function(callback) {
        try {
            this.forEach(function(element) {
                if (!callback(element)) {
                    throw new StopIteration();
                }
            });
        } catch(err) {
            return false;
        }

        return true;
    },

    /**
     * Returns true if the callback ever returns a thruthy value
     */
    any: function(callback) {
        try {
            this.forEach(function(element) {
                if (!!callback(element)) {
                    throw new StopIteration();
                }
            });
        } catch(err) {
            return true;
        }

        return false;
    },

    /**
     * Returns a new array with the results of running the callback
     * once for every element in the collection.
     */
    collect: function(callback) {
        var newEnum = [];

        this.forEach(function(element) {
            newEnum.push(callback(element));
        });

        return newEnum;
    }
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Dette er tre av metodene som Rubys enumerable tilbyr. Merk at siden vi looper samlingene med callbacks er exceptions den eneste måten vi kan avbryte en loop på. For 				&lt;code&gt;all&lt;/code&gt;-metoden vet vi for eksempel at vi ikke trenger å loope mer så fort vi får en ikke-sann verdi fra callback-metoden. Tilsvarende kan vi avbryte så fort vi har fått en sann verdi for 				&lt;code&gt;any&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Det eneste vi mangler nå er å legge til denne funksjonaliteten for arrayer. Dette kan vi enkelt oppnå med 				&lt;code&gt;extend&lt;/code&gt;-metoden, som for anledningen har fått aliaset 				&lt;code&gt;mixin&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;mixin(Array.prototype, cj.Enumerable);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Merk aliaset 				&lt;code&gt;mixin&lt;/code&gt;. Dette er en enkel sak:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var mixin = extend;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/mixins/test2.html&quot;&gt;Testene våre bekrefter at denne implementasjonen duger&lt;/a&gt;. For arrayer. Hva med andre samlinger?
&lt;/p&gt;
	&lt;h3 id=&quot;toc17116_1_1&quot;&gt;Styrken med mixins&lt;/h3&gt;
&lt;p&gt;
Styrken med mixins viser seg når vi nå mikser inn modulen vår i en nodeliste. En av testene våre så ut som:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testCollect: function() { with(this) {
    var array = [document.getElementById(&amp;quot;list&amp;quot;), document.getElementById(&amp;quot;something&amp;quot;)];

    assertEnumEqual([&amp;quot;ul&amp;quot;, &amp;quot;div&amp;quot;], array.collect(function(element) {
        return element.tagName.toLowerCase();
    }));
}}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Legg merke til at &amp;quot;list&amp;quot; og &amp;quot;something&amp;quot; er idene på to elementer som kunne vært hentet med 				&lt;code&gt;document.getElementById(&amp;quot;sample&amp;quot;).getElementsByTagName(&amp;quot;*&amp;quot;);&lt;/code&gt;. Denne metoden returnerer et 				&lt;code&gt;NodeList&lt;/code&gt;-objekt. La oss gi 				&lt;code&gt;NodeList&lt;/code&gt;-objektet en 				&lt;code&gt;forEach&lt;/code&gt;-metode, og deretter all funksjonalitet i 				&lt;code&gt;cj.Enumerable&lt;/code&gt;. Det fungerer desverre ikke å bare legge funksjonalitet på 				&lt;code&gt;NodeList.prototype&lt;/code&gt; som vi er vant til, så vi må mikse inn funksjonaliteten på enkelte objekter.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testCollectNodeList: function() { with(this) {
    var elements = document.getElementById(&amp;quot;sample&amp;quot;).getElementsByTagName(&amp;quot;*&amp;quot;);
    elements = enumerableNodeList(elements);

    assertEnumEqual([&amp;quot;ul&amp;quot;, &amp;quot;div&amp;quot;], elements.collect(function(element) {
        return element.tagName.toLowerCase();
    }));
}}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/mixins/test3.html&quot;&gt;Testen feiler&lt;/a&gt; selvsagt, så la oss skrive litt kode. Fordi vi ikke kan utvide prototypen som vi pleier har vi lagt opp til en metode som returnerer en enumerable nodeliste. Implementasjonen av 				&lt;code&gt;Array.prototype.forEach&lt;/code&gt; er såppass generisk at vi kan kopiere den direkte over på nodelisten:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function enumerableNodeList(list) {
    // Already extended
    if (list.all) {
        return list;
    }

    // Borrow arrays foreach iterator
    list.forEach = Array.prototype.forEach;

    // Return extended object
    return mixin(list, cj.Enumerable);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/mixins/test4.html&quot;&gt;Mer skulle ikke til&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Dersom du liker det du ser kan jeg informere om at 			
											
			&lt;a href=&quot;http://prototypejs.org/api/enumerable&quot; hreflang=&quot;en&quot;&gt;prototype.js har en full Enumerable-implementasjon&lt;/a&gt; som ligner på den vi har sett her idag.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen for en diskusjon av debugging og profilering av JavaScript.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>19 Dec 2008 00:02:28 GMT</pubDate>
  <title>En nyttigere document.createElement</title>
  <link>http://www.cjohansen.no/javascript/en_nyttigere_document_createelement</link>
  <guid>http://www.cjohansen.no/javascript/en_nyttigere_document_createelement</guid>
  <comments>http://www.cjohansen.no/javascript/en_nyttigere_document_createelement#comments</comments>
  <description>
    
&lt;p&gt;
Å opprette nye elementer med nettlesernes DOM-APIer er tungvindt og &amp;quot;verbost&amp;quot;. Idag bygger vi en hjelpemetode som lager nye elementer på en langt mer kompakt måte.
&lt;/p&gt;

    
&lt;p&gt;
Nok en tutorial idag altså. Målene er de samme som sist:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Først og fremst: Lære. Se et litt mer komplekst eksempel&lt;/li&gt;

&lt;li&gt;Øve på testdrevet utvikling&lt;/li&gt;

&lt;li&gt;Å lage et verktøy som kan hjelpe til i små prosjekter der rammeverk på 100k blir overkill&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Som en ekstra bonus kommer vi til sist til å &lt;b&gt;bygge dagens kode sammen med 				&lt;code&gt;$&lt;/code&gt;-funksjonen fra sist&lt;/b&gt; - en illustrasjon i hvordan koden fra sist er fleksibel nok til å la seg enkelt utvide.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17106_1&quot;&gt;Utgangspunktet&lt;/h2&gt;
&lt;p&gt;
Tanken er å lage en metode som kan lage et element, og i samme operasjon sette vilkårlig mange attributter &lt;b&gt;og&lt;/b&gt; innholdet. Noen enhetstester sier mer enn, vel, mange ord.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var createElementTestCase = new YAHOO.tool.TestCase({
    name: &amp;quot;Create DOM element utility&amp;quot;,

    testCreateWithTagName: function() {
        var assert = YAHOO.util.Assert;

        var element = createElement(&amp;quot;a&amp;quot;);
        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(1, element.nodeType);
        assert.areEqual(&amp;quot;a&amp;quot;, element.tagName.toLowerCase());

        element = createElement(&amp;quot;div&amp;quot;);
        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(1, element.nodeType);
        assert.areEqual(&amp;quot;div&amp;quot;, element.tagName.toLowerCase());
    },

    testCreateWithAttributes: function() {
        var assert = YAHOO.util.Assert;

        var element = createElement(&amp;quot;a&amp;quot;, {
            href: &amp;quot;http://www.cjohansen.no/&amp;quot;,
            className: &amp;quot;external&amp;quot;
        });

        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(&amp;quot;http://www.cjohansen.no/&amp;quot;, element.href);
        assert.areEqual(&amp;quot;external&amp;quot;, element.className);
    },

    testCreateWithContent: function() {
        var assert = YAHOO.util.Assert;

        var element = createElement(&amp;quot;a&amp;quot;, {}, &amp;quot;Link text&amp;quot;);
        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(&amp;quot;Link text&amp;quot;, element.innerHTML);
    },

    testCreateWithParent: function() {
        var assert = YAHOO.util.Assert;

        var element = createElement(&amp;quot;a&amp;quot;, {}, null, document.body);
        var links = document.body.getElementsByTagName(&amp;quot;a&amp;quot;);

        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(1, links.length);
        assert.areEqual(element, links[0]);
    },

    testCreateFull: function() {
        var assert = YAHOO.util.Assert;

        var element = createElement(&amp;quot;a&amp;quot;, {
            href: &amp;quot;http://www.cjohansen.no/&amp;quot;,
            id: &amp;quot;cjlink&amp;quot;
        }, &amp;quot;cjohansen.no&amp;quot;, document.body);

        var link = document.getElementById(&amp;quot;cjlink&amp;quot;);

        assert.isInstanceOf(HTMLElement, element);
        assert.areEqual(element, link);
        assert.areEqual(&amp;quot;http://www.cjohansen.no/&amp;quot;, element.href);
    }
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/en_nyttigere_document_createelement/test1.html&quot;&gt;Testene feiler&lt;/a&gt;, og utgjør et fint mål. Metoden skal kunne lage et element med følgende data:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;				&lt;code&gt;tagName&lt;/code&gt; - elementtypen som skal lages&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;attributes&lt;/code&gt; - en objektliteral med attributtnavn som egenskapnavn og attributtverdier som verdier&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;content&lt;/code&gt; - tekst eller HTML som skal settes inn i det nye elementet&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;parent&lt;/code&gt; - foreldreelementet, hvis noe&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Kun tagnavnet er påkrevd. Implementasjonen er relativt rett frem:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function createElement(tagName, attributes, content, parent) {
    var element = document.createElement(tagName);
    attributes = attributes || {};

    // Set attributes
    for (var attr in attributes) if (attributes.hasOwnProperty(attr)) {
        element[attr] = attributes[attr];
    }

    // Add content, if provided
    if (content) {
        element.innerHTML = content;
    }

    // Add to parent, if provided
    if (parent) {
        parent.appendChild(element);
    }

    return element;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Heldig for oss så var vi smarte nok i første omgang til at 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/en_nyttigere_document_createelement/test2.html&quot;&gt;testene nå kjører&lt;/a&gt;.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17106_2&quot;&gt;Integrere i 				&lt;code&gt;cj.Element&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;
Forleden dag laget vi jo et navnerom for element-utvidelser, og denne metoden kunne passe godt inn der. For eksempel kunne det være nyttig å gjøre:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var div = $(&amp;quot;testDiv&amp;quot;);
div.create(&amp;quot;a&amp;quot;, { href: &amp;quot;http://www.cjohansen.no/&amp;quot; }, &amp;quot;cjohansen.no&amp;quot;);

// Resultat:
// &amp;lt;div id=&amp;quot;testDiv&amp;quot;&amp;gt;
//   &amp;lt;!-- HTML fra tidligere --&amp;gt;
//   &amp;lt;a href=&amp;quot;http://www.cjohansen.no/&amp;quot;&amp;gt;cjohansen.no&amp;lt;/a&amp;gt;
// &amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Eller formulert som en ny test:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testCreateFromElement: function() {
    var assert = YAHOO.util.Assert;

    var body = $(document.body);
    var element = body.create(&amp;quot;div&amp;quot;, { id: &amp;quot;testDiv&amp;quot; });

    assert.isInstanceOf(HTMLElement, element);
    assert.isNotUndefined(element.hasClassName);
    assert.areEqual($(&amp;quot;testDiv&amp;quot;), element);
    assert.areEqual(document.body, element.parentNode);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Problemet med den nye metoden vår er bare at den ikke tar et element som første parameter - parent-parameteret er det siste metoden tar. Dette gir meningen når metoden kalles som tidligere fordi parent ofte er null. Men, vi kan trikse litt. Når metoden kjøres gjennom et annet element (				&lt;code&gt;element.create(/* ... */);&lt;/code&gt; så kan vi ta første parameter som foreldreelement, mens vi ellers behandler parameterne som tidligere. Det høres kanskje vanskeligere ut enn det er:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;cj.Element = {
    /* ... */

    create: function() {
        var tagName, attributes, content, parent;

        // If first argument is an HTMLElement, we're running from within
        // an element
        if (arguments[0] instanceof HTMLElement) {
            parent = arguments[0];
            tagName = arguments[1] || parent.tagName;
            attributes = arguments[2] || {};
            content = arguments[3] || null;
        } else {
            tagName = arguments[0];
            attributes = arguments[1] || {};
            content = arguments[2] || null;
            parent = arguments[3] || null;
        }

        var element = document.createElement(tagName);
        attributes = attributes || {};

        // Set attributes
        for (var attr in attributes) if (attributes.hasOwnProperty(attr)) {
            element[attr] = attributes[attr];
        }

        // Add content, if provided
        if (content) {
            element.innerHTML = content;
        }

        // Add to parent, if provided
        if (parent) {
            parent.appendChild(element);
        }

        // If called from an element, ie element.create(/* ... */)
        // extend new element as well
        if (arguments[0] instanceof HTMLElement) {
            cj.Element.extend(element);
        }

        return element;
    }
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Metoden er ellers som den var, og 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/en_nyttigere_document_createelement/test3.html&quot;&gt;testene kjører fortsatt&lt;/a&gt;. Merk at jeg i dette siste eksempelet har inkludert all kode og tester fra sist også.
&lt;/p&gt;

&lt;p&gt;
Og dermed har vi sett et eksempel på hvordan element-verktøyet vårt fra sist kan videreutvikles med mer funksjonalitet. Det er slike ting som ligger i bunnen av rammeverkene vi bruker, og det er morsomt å jobbe seg gjennom noen praktiske eksempler for å bedre forstå de underliggende problemene som vi er vant til å få abstrahert bort gjennom rammeverkene.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen for en prat om mixins og multippel arv i JavaScript.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>18 Dec 2008 00:14:47 GMT</pubDate>
  <title>Metodekjeder i JavaScript</title>
  <link>http://www.cjohansen.no/javascript/metodekjeder_i_javascript</link>
  <guid>http://www.cjohansen.no/javascript/metodekjeder_i_javascript</guid>
  <comments>http://www.cjohansen.no/javascript/metodekjeder_i_javascript#comments</comments>
  <description>
    
&lt;p&gt;
Å kjede sammen metodekall kan resultere i kompakt kode med relativt høy leselighet. jQuery har tatt dette til det ekstreme. Vi ser litt på hvordan dette fungerer, og noen praktiske eksempler.
&lt;/p&gt;

    
&lt;p&gt;
Kjeding av metodekall benyttes ofte når man ønsker å konstruere et såkalt DSL - Domain Specific Language. Som navnet antyder så er et domenespesifikt språk (vanligvis) et API hvor metodene har navn som gjør at kode mot APIet får karakteristikker av et eget språk. Jeg laget for eksempel et slikt DSL til min valideringskomponent, 			
									
												
			&lt;a href=&quot;http://www.validatious.org&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Validatious&lt;/a&gt;, som ser ut som:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;validate(
    &amp;quot;name&amp;quot;.is(&amp;quot;required&amp;quot;).explain(&amp;quot;Please enter your name&amp;quot;),
    &amp;quot;email&amp;quot;.is(&amp;quot;required&amp;quot;).explain(&amp;quot;Please enter your email&amp;quot;).andIsAn(&amp;quot;email&amp;quot;),
    or(
        &amp;quot;home_phone&amp;quot;.isA(&amp;quot;phone-num&amp;quot;).andIs(&amp;quot;required&amp;quot;),
        &amp;quot;office_phone&amp;quot;.isA(&amp;quot;phone-num&amp;quot;).andIs(&amp;quot;required&amp;quot;)
    ).explain(&amp;quot;Enter either home or office phone number&amp;quot;)
);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Koden over oppnår på 8 linjer å legge valideringslogikk på et skjema som:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;sjekker at navn er oppgitt&lt;/li&gt;

&lt;li&gt;kommer med en tilpasset feilmelding dersom navn mangler&lt;/li&gt;

&lt;li&gt;sjekker at e-post er oppgitt&lt;/li&gt;

&lt;li&gt;kommer med en tilpasset feilmelding dersom e-post mangler&lt;/li&gt;

&lt;li&gt;kommer med en standardmelding dersom e-posten har feil format&lt;/li&gt;

&lt;li&gt;sjekker om en av telefonnummerne er oppgitt&lt;/li&gt;

&lt;li&gt;kommer med en tilpasset feilmelding dersom begge telefonnummerne er tomme, eller har syntaksfeil&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Dette klarte du sikkert selv å lese av det ovenforstående, takket være den ekspressive syntaksen man oppnår med slike APIer.
&lt;/p&gt;

&lt;p&gt;
Metodekjeding er det sentrale temaet som står bak et slikt API. Det er ikke vanskelig, det dreier seg kun om returverdier.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17096_1&quot;&gt;Et enkelt eksempel&lt;/h2&gt;
&lt;p&gt;
Metodekjeding har flere bruksområder enn å lage DSL-er. Et enklere eksempel er å lage DOM-elementer, en oppgave som med DOM-APIet kan bli ganske voldsom:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var link = document.createElement(&amp;quot;a&amp;quot;);
link.href = &amp;quot;http://www.cjohansen.no&amp;quot;;
link.className = &amp;quot;external&amp;quot;;
link.appendChild(document.createTextNode(&amp;quot;Christians blogg&amp;quot;));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
La oss se for oss følgende hjelpemetode:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function createElement(tagName) {
    var element = document.createElement(tagName);

    element.set = function(property, value) {
        if (property === &amp;quot;text&amp;quot;) {
            this.appendChild(document.createTextNode(value));
        } else {
            this[property] = value;
        }

        return this;
    };

    return element;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Med denne blir syntaksen litt annerledes:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var link = createElement(&amp;quot;a&amp;quot;).
             set(&amp;quot;href&amp;quot;, &amp;quot;http://www.cjohansen.no&amp;quot;).
             set(&amp;quot;className&amp;quot;, &amp;quot;external&amp;quot;).
             set(&amp;quot;text&amp;quot;, &amp;quot;Christians blogg&amp;quot;);

// Lage heading - gammel måte
var heading = document.createElement(&amp;quot;h1&amp;quot;);
heading.appendChild(document.createTextNode(&amp;quot;Heading&amp;quot;));

// Lage heading - ny måte
var heading = createElement(&amp;quot;h1&amp;quot;).set(&amp;quot;text&amp;quot;, &amp;quot;Heading&amp;quot;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
&amp;quot;Trikset&amp;quot; når vi gjør metodekjeding som dette er rett og slett å returnere 				&lt;code&gt;this&lt;/code&gt; i metoder som vanligvis ikke har noen returverdi. Det kan ofte spare deg for noen linjer snekkerkode og gi koden bedre flyt. Kjeding kan også dras for langt, og ikke alle er like begeistreit for stilen.
&lt;/p&gt;

&lt;p&gt;
Innledningsvis viste jeg et eksempel fra mitt prosjekt &lt;i&gt;Validatious&lt;/i&gt;. Her er konseptet dratt relativt langt - til et validerings-DSL - men konseptet er det samme. Alle metodene returnerer objekter, ofte av samme type - men ikke alltid.
&lt;/p&gt;

&lt;p&gt;
I Validatious sin 				&lt;code&gt;v2.dsl&lt;/code&gt; er det for eksempel 4 &amp;quot;klasser&amp;quot; du hopper mellom når du bruker API-et. For brukeren (altså den som koder mot DSL API-et) er dette for det meste ikke synlig - annet enn at &amp;quot;etter kall A kan du kalle C, D og E&amp;quot;. For meg som lager det gir det meg samme mulighet til å strukturere koden min som vanlig.
&lt;/p&gt;

&lt;p&gt;
jQuery er et annet eksempel hvor kjeding dras langt:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;$('form#login')
    // hide all the labels inside the form with the 'optional' class
    .find('label.optional').hide().end()
    // add a red border to any password fields in the form
    .find('input:password').css('border', '1px solid red').end()
    // add a submit handler to the form
    .submit(function(){
        return confirm('Are you sure you want to submit?');
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Hvorvidt dette er en forbedring eller ikke blir en smakssak, men det gir mulighet for en ganske annerledes måte å kode JavaScript på. Dette eksempelet er ikke overdrevent langt i forhold til mitt Validatious-eksempel fra tidligere, men det er to viktige forskjeller:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;b&gt;hele&lt;/b&gt; greia er én eneste linje&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;end()&lt;/code&gt; reverserer utvalget fra det som finnes med 				&lt;code&gt;find()&lt;/code&gt; til det opprinnelige skjemaet&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Nettopp det siste punktet kan gi kode som er ganske tricky å lese - og da er det kanskje like greit å heller gjøre det i flere steg? Metodekjeding kan definitivt sprite opp APIene dine og gi deg mer kompakt kode, men mer kompakt er ikke alltid bare bra.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen for implementering av en nyttigere 				&lt;code&gt;document.createElement&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Har du noen tanker om kjeding av metoder eller andre interessante eksempler/innspill? Legg gjerne igjen en kommentar!
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>17 Dec 2008 00:04:11 GMT</pubDate>
  <title>Hjelperen $()</title>
  <link>http://www.cjohansen.no/javascript/hjelperen</link>
  <guid>http://www.cjohansen.no/javascript/hjelperen</guid>
  <comments>http://www.cjohansen.no/javascript/hjelperen#comments</comments>
  <description>
    
&lt;p&gt;
De fleste rammeverkene tilbyr en &amp;quot;magisk&amp;quot; &amp;quot;dollarfunksjon&amp;quot;. Vi ser litt på hva den ofte gjør, og hvordan den kan realiseres.
&lt;/p&gt;

    
&lt;p&gt;
Dagens innlegg er først og fremst en tutorial. Når vi er ferdig kan vi gjøre følgende:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var element = $(&amp;quot;element&amp;quot;);
element.addClassName(&amp;quot;super&amp;quot;);
console.log(element.hasClassName(&amp;quot;super&amp;quot;)); // true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Formålet med denne øvelsen er:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Først og fremst: Lære. Se et litt mer komplekst eksempel&lt;/li&gt;

&lt;li&gt;Øve på testdrevet utvikling&lt;/li&gt;

&lt;li&gt;Å lage et verktøy som kan hjelpe til i små prosjekter der rammeverk på 100k blir overkill&lt;/li&gt;

&lt;/ul&gt;
	&lt;h2 id=&quot;toc17086_1&quot;&gt;Bakgrunn&lt;/h2&gt;
&lt;p&gt;
De fleste rammeverkene har en funksjon hvis navn kun er et dollartegn. Både 			
									
												
			&lt;a href=&quot;http://prototypejs.org/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;prototype.js&lt;/a&gt; og 			
									
												
			&lt;a href=&quot;http://jquery.com/&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;jQuery&lt;/a&gt; var tidlig ute med dette. Vanligvis fungerer dollaren slik at den &lt;b&gt;henter elementer på id&lt;/b&gt; (altså samme som 				&lt;code&gt;document.getElementById(id)&lt;/code&gt;) - men i tillegg er det &lt;b&gt;returnerte elementet utvidet med HTML-spesifikk nyttefunksjonalitet&lt;/b&gt; så som feks 				&lt;code&gt;addClassName(className)&lt;/code&gt; eller 				&lt;code&gt;computedStyle(property)&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
I tillegg er det vanlig at funksjonen er litt &lt;b&gt;fleksibel i forhold til input&lt;/b&gt; - gir du den et DOM-element får du det tilbake med ekstra funksjonalitet og gir du den en array får du en array med elementer tilbake. På denne måten kan du eksempelvis kalle funksjonen uavhengig om du vet om en verdi er en streng (id på felt) eller et faktisk felt.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17086_2&quot;&gt;Spesifikasjon&lt;/h2&gt;
&lt;p&gt;
Ok, før vi begynner kan vi starte med en kort liste over funksjonalitet:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Støtte flere typer input:
&lt;ul&gt;

&lt;li&gt;en enkelt streng (returnerer ett enkelt element)&lt;/li&gt;

&lt;li&gt;et enkelt element (returnerer dette elementet)&lt;/li&gt;

&lt;li&gt;flere strenger og/eller elementer (returnerer en array med elementer)&lt;/li&gt;

&lt;li&gt;en array med strenger og/eller elementer (returnerer en array med elementer)&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;Returnerte elementer skal støtte metodene 				&lt;code&gt;hasClassName&lt;/code&gt;, 				&lt;code&gt;addClassName&lt;/code&gt; og 				&lt;code&gt;removeClassName&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Mulighet for å enkelt legge til metoder som de returnerte elementene skal støtte&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Legg merke til at det er forskjell mellom å ta imot vilkårlig mange strenger og en array med strenger:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;$(&amp;quot;vilkårlig&amp;quot;, &amp;quot;mange&amp;quot;, &amp;quot;strenger&amp;quot;);
$([&amp;quot;en&amp;quot;, &amp;quot;array&amp;quot;, &amp;quot;med&amp;quot;, &amp;quot;strenger&amp;quot;])&lt;/code&gt;&lt;/pre&gt;
	&lt;h2 id=&quot;toc17086_3&quot;&gt;Testoppsett&lt;/h2&gt;
&lt;p&gt;
Vi bruker YUI Test, og har følgende simple test-HTML:
&lt;/p&gt;

    &lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;div id=&amp;quot;sample&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;sample2&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;sample3&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
i tillegg har testcaset en setup-metode, denne kjøres før hver test i testcaset:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;setUp: function() {
    this.sample = document.getElementById(&amp;quot;sample&amp;quot;);
    this.sample2 = document.getElementById(&amp;quot;sample2&amp;quot;);
    this.sample3 = document.getElementById(&amp;quot;sample3&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
	&lt;h2 id=&quot;toc17086_4&quot;&gt;Finne elementer&lt;/h2&gt;
&lt;p&gt;
La oss starte med å hente elementer. Funksjonen skal støtte et mangfold av input. Vi ser for oss en metode 				&lt;code&gt;getElements&lt;/code&gt; i navnerommet 				&lt;code&gt;cj&lt;/code&gt; som gjør denne jobben:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testGetWithStrings: function() {
    var assert = YAHOO.util.Assert;

    // Single string
    assert.areEqual(this.sample, cj.getElements(&amp;quot;sample&amp;quot;));

    // Arbitrary many arguments
    var elements = cj.getElements(&amp;quot;sample&amp;quot;, &amp;quot;sample1&amp;quot;);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);

    // Array argument
    elements = cj.getElements([&amp;quot;sample&amp;quot;, &amp;quot;sample1&amp;quot;]);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);
},

testGetWithElements: function() {
    var assert = YAHOO.util.Assert;

    // Single element
    assert.areEqual(this.sample, cj.getElements(this.sample));

    // Arbitrary many arguments
    var elements = cj.getElements(this.sample, this.sample1);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);

    // Array argument
    elements = cj.getElements([this.sample, this.sample1]);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);
},

testGetWithMixed: function() {
    var assert = YAHOO.util.Assert;

    // Arbitrary many arguments
    var elements = cj.getElements(&amp;quot;sample&amp;quot;, this.sample1);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);

    // Array argument
    elements = cj.getElements([this.sample, &amp;quot;sample1&amp;quot;]);
    assert.areEqual(this.sample, elements[0]);
    assert.areEqual(this.sample1, elements[1]);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test1.html&quot;&gt;Kjør testene&lt;/a&gt; (de skal feile).
&lt;/p&gt;
	&lt;h3 id=&quot;toc17086_4_1&quot;&gt;Implementasjonen&lt;/h3&gt;
&lt;p&gt;
Implementasjonen er relativt rett frem:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var cj = {};

cj.getElements = function() {
    // Extract array argument
    var args = arguments;
    args = args.length === 1 &amp;amp;&amp;amp; args[0] instanceof Array ? args[0] : args;

    // Return array if there were more than one argument
    // (or argument was an array)
    if (args.length &amp;gt; 1) {
        var results = [];

        for (var i = 0; i &amp;lt; args.length; i++) {
            results.push(cj.getElements(args[i]));
        }

        return results;
    }

    // Process single argument
    return typeof args[0] === &amp;quot;string&amp;quot; ?
           document.getElementById(args[0]) : args[0];
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Jeg minner om at 				&lt;code&gt;arguments&lt;/code&gt; er en array-lignende verdi som inneholder en liste med alle parameterne funksjonen ble kalt med. Dersom det er flere enn én parameter, eller det ene parameteret er en array kjører vi funksjonen for hver enkelt parameter og returnerer resultatet i en array.
&lt;/p&gt;

&lt;p&gt;
Vi kan verifisere at denne koden løser det nåværende problemet ved å 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test2.html&quot;&gt;kjøre testene&lt;/a&gt;.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17086_5&quot;&gt;Ekstrafunksjonalitet&lt;/h2&gt;
&lt;p&gt;
Nå som vi har funksjonen som henter elementer på plass kan vi se på tilleggsfunksjonaliteten. Det ble nevnt at det skal være nogenlunde lett å legge til tilleggsfunksjonalitet, så det kan jo være en idé å samle alle utvidelses-metodene i et eget navnerom. Vi snakker jo om elementer, så 				&lt;code&gt;cj.Element&lt;/code&gt; gir mening.
&lt;/p&gt;

&lt;p&gt;
La oss for øyeblikket skyve til siden det faktum at metodene skal settes på de returnerte objektene, og heller implementere funksjoner som kan kalles med elementet som parameter:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testHasClassName: function() {
    var assert = YAHOO.util.Assert;

    assert.isFalse(cj.Element.hasClassName(this.sample, 'test'));

    this.sample.className = &amp;quot;holy moly&amp;quot;;
    assert.isTrue(cj.Element.hasClassName(this.sample, 'holy'));
    assert.isFalse(cj.Element.hasClassName(this.sample, 'hol'));
},

testAddClassName: function() {
    var assert = YAHOO.util.Assert;

    cj.Element.addClassName(this.sample, 'test');
    assert.areEqual('test', this.sample.className);
    assert.isTrue(cj.Element.hasClassName(this.sample, 'test'));

    cj.Element.addClassName(this.sample, 'another');
    assert.areEqual('test another', this.sample.className);
},

testRemoveClassName: function() {
    var assert = YAHOO.util.Assert;
    this.sample.className = &amp;quot;test another&amp;quot;;
    cj.Element.removeClassName(this.sample, &amp;quot;another&amp;quot;);
    assert.areEqual(&amp;quot;test&amp;quot;, this.sample.className);

    cj.Element.removeClassName(this.sample, &amp;quot;bla&amp;quot;);
    assert.areEqual(&amp;quot;test&amp;quot;, this.sample.className);

    cj.Element.removeClassName(this.sample, &amp;quot;test&amp;quot;);
    assert.areEqual(&amp;quot;&amp;quot;, this.sample.className);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test3.html&quot;&gt;Kjør testene&lt;/a&gt; (de feiler).
&lt;/p&gt;
	&lt;h3 id=&quot;toc17086_5_1&quot;&gt;Implementasjon&lt;/h3&gt;
&lt;p&gt;
Implementasjonen her er ganske rett frem. For å legge til klassenavnet er det bare å legge til en space og det nye klassenavnet. Fjerning og testing på klassenavnet kan gjøres med et regulært uttrykk. Som illustrert i 				&lt;code&gt;testHasClassName&lt;/code&gt; er vi nøye på å sjekke at 				&lt;code&gt;hasClassName(&amp;quot;tes&amp;quot;)&lt;/code&gt; gir feil når elementet har klassen 				&lt;code&gt;test&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Nå som vi har et navnerom 				&lt;code&gt;cj.Element&lt;/code&gt; føles det jo naturlig for 				&lt;code&gt;getElements&lt;/code&gt; også å ligge her, så vi døper i samme slengen den om til 				&lt;code&gt;cj.Element.get&lt;/code&gt;. Hele løsningen så langt ser da ut som:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
};

var cj = {};

cj.Element = {
    get: function() {
        // Extract array argument
        var args = arguments;
        args = args.length === 1 &amp;amp;&amp;amp; args[0] instanceof Array ? args[0] : args;

        if (args.length &amp;gt; 1) {
            var results = [];

            for (var i = 0; i &amp;lt; args.length; i++) {
                results.push(cj.getElements(args[i]));
            }

            return results;
        }

        // Process single argument
        return typeof args[0] === &amp;quot;string&amp;quot; ?
           document.getElementById(args[0]) : args[0];
    },

    hasClassName: function(element, className) {
        return new RegExp(&amp;quot;\\b&amp;quot; + className + &amp;quot;\\b&amp;quot;).test(element.className);
    },

    addClassName: function(element, className) {
        if (!cj.Element.hasClassName(element, className)) {
            element.className = (element.className + &amp;quot; &amp;quot; + className).trim();
        }
    },

    removeClassName: function(element, className) {
        var regex = new RegExp(&amp;quot;\\b&amp;quot; + className + &amp;quot;\\b&amp;quot;);
        element.className = element.className.replace(regex, &amp;quot;&amp;quot;).replace(/\s+/, &amp;quot; &amp;quot;);
    }
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test4.html&quot;&gt;Kjør testene&lt;/a&gt;. Oops! Nå kjører klassenavn-testene våre, men metoden som finner elementer feiler i alle tre testene. Vel, det viser seg at vi bare har glemt å reflektere refaktoreringen i testene våre. Det fikser vi fort, 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test5.html&quot;&gt;voila&lt;/a&gt;!
&lt;/p&gt;
	&lt;h2 id=&quot;toc17086_6&quot;&gt;Utvidede elementer&lt;/h2&gt;
&lt;p&gt;
I implementasjonen over hentet jeg inn 				&lt;code&gt;String.prototype.trim&lt;/code&gt;-implementasjonen som vi gjorde tidligere. Hvorfor løste jeg ikke klassenavns-funksjonene på tilsvarende måte (altså ved å legge dem i noens prototype)? Vel, jeg kunne ha gjort som følger:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;HTMLElement.prototype.hasClassName = function(className) {
    return new RegExp(&amp;quot;\\b&amp;quot; + className + &amp;quot;\\b&amp;quot;).test(this.className);
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
...og det ville ha fungerte i alle &lt;b&gt;fornuftige&lt;/b&gt; nettlesere. Dette inkluderer som kjent ikke Internet Exploder. I IE fungerer det ikke å jobbe med prototypen til Element (eller HTMLElement). Dette fungerer for eksempel i Firefox, og da vil det også funke selvom du henter elementene &amp;quot;manuelt&amp;quot; via 				&lt;code&gt;document.getElementById(id)&lt;/code&gt;. Men siden IE ikke er med på leken må vi utvide enkeltelementer.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17086_6_1&quot;&gt;				&lt;code&gt;extend&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
Ok, så la oss lage en funksjon som utvider et element:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testExtend: function() {
    var assert = YAHOO.util.Assert;

    cj.Element.extend(this.sample2);
    assert.isNotUndefined(this.sample2.hasClassName);
    assert.isFalse(this.sample2.hasClassName(&amp;quot;test&amp;quot;));

    this.sample2.className = &amp;quot;test&amp;quot;;
    assert.isTrue(this.sample2.hasClassName(&amp;quot;test&amp;quot;));

    assert.isUndefined(this.sample2.get, &amp;quot;Get method should not be transferred&amp;quot;);
    assert.isUndefined(this.sample2.extend, &amp;quot;Extend method should not be transferred&amp;quot;);
    assert.isNotUndefined(this.sample2.addClassName);
},

testAutoExtend: function() {
    var assert = YAHOO.util.Assert;
    var sample3 = document.getElementById(&amp;quot;sample3&amp;quot;);

    var sample3b = cj.Element.get(&amp;quot;sample3&amp;quot;);
    assert.areEqual(sample3, sample3b);
    assert.isNotUndefined(sample3.hasClassName);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Den siste testen er ment å sjekke at elementer er utvidet automatisk (altså gjennom prototypen til 				&lt;code&gt;HTMLElement&lt;/code&gt;). Den vil aldri passere i IE. 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test6.html&quot;&gt;Kjør testen&lt;/a&gt; (som feiler).
&lt;/p&gt;
	&lt;h3 id=&quot;toc17086_6_2&quot;&gt;Implementasjon&lt;/h3&gt;
&lt;p&gt;
Implementasjonen av denne metoden er denne tutorialens mest interessante. La oss se koden først og gå gjennom den etterpå:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;extend: function(element) {
    // Already extended, abort
    if (element.hasClassName) {
        return element;
    }

    // Loop all methods in cj.Element
    for (var method in cj.Element) if (cj.Element.hasOwnProperty(method)) {
        // Skip get() and extend()
        if (method === &amp;quot;get&amp;quot; || method === &amp;quot;extend&amp;quot;) {
            continue;
        }

        // Anonymous closure - scope
        (function() {
            var methodName = method;

            // Extend element with method
            element[methodName] = function() {
                // First argument is element
                var args = [element];

                // Complete argument list with arguments passed to the method
                for (var i = 0; i &amp;lt; arguments.length; i++) {
                    args.push(arguments[i]);
                }

                // Run original method in elements context
                return cj.Element[methodName].apply(element, args);
            };
        })();
    }

    return element;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Aller først sjekker vi at elementet ikke allerede er utvidet ved å teste for en vilkårlig valgt utvidelses-metode. &lt;b&gt;På denne måten unngår vi å utvide elementer mer enn én gang&lt;/b&gt;. Senere skal dette bli nyttig i nettlesere hvor prototype-magien er nok, da vil ingen enkeltelementer bli utvidet på denne måten fordi de allerede arver funksjonaliteten gjennom prototypen sin.
&lt;/p&gt;

&lt;p&gt;
Neste skritt er å loope gjennom alle metodene i 				&lt;code&gt;cj.Element&lt;/code&gt;. Vi sjekker at vi ikke ved en feil får egenskaper og/eller metoder som arves fra prototypekjeden ved å sjekke 				&lt;code&gt;cj.Element.hasOwnProperty(method)&lt;/code&gt;, og deretter avbryter vi dersom metoden er &lt;i&gt;get&lt;/i&gt; eller &lt;i&gt;extend&lt;/i&gt; - disse trenger ikke å legges til på elementet.
&lt;/p&gt;

&lt;p&gt;
Så blir det interessant:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;Metoden vi tilordner elementet skaper en closure. Denne closuren vil i utgangspunktet ha referanse til det samme lokale skopet for alle metodene, noe som vil føre til at 				&lt;code&gt;method&lt;/code&gt; i loopen vil være den samme verdien for alle metodene. For å unngå dette lager vi en anonym closure for å redefinere skopet og setter metodenavnet i en lokal variabel. (Puh!)&lt;/li&gt;

&lt;li&gt;Vi benytter oss av at i JavaScript så er 				&lt;code&gt;obj[prop] === obj.prop&lt;/code&gt; for alle typer verdier (også metoder) og tilordner en ny metode på elementet.&lt;/li&gt;

&lt;li&gt;Fremfor å tilordne metoden fra 				&lt;code&gt;cj.Element&lt;/code&gt; direkte tilordner vi en anonym funksjon som legger til elementet som utvides som første parameter.&lt;/li&gt;

&lt;li&gt;Den anonyme funksjonen kjører den opprinnelige metoden med elementet som første parameter til 				&lt;code&gt;apply&lt;/code&gt; (dvs at 				&lt;code&gt;this&lt;/code&gt; inne i metoden i cj.Element vil være elementet når metoden kjøres via elementet).&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
Det dette betyr er at vi nå kan legge til så mange metoder vi bare vil i 				&lt;code&gt;cj.Element&lt;/code&gt;, så lenge metoden tar et element som første parameter. Vi kan verifisere ved å 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test7.html&quot;&gt;kjøre testene&lt;/a&gt;.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17086_7&quot;&gt;Autoextending og sammenkobling&lt;/h2&gt;
&lt;p&gt;
Foreløpig skjer det ikke noe extending fra 				&lt;code&gt;cj.Element.get&lt;/code&gt;. Dette er en triviell sak å ordne:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;// Siste linje i cj.Element.get endres til
return cj.Element.extend(typeof args[0] === &amp;quot;string&amp;quot; ?
       document.getElementById(args[0]) : args[0]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Et annet problem er at autoextending ikke virker. Det er ikke så rart siden vi ikke har gjort noe for å få det til. Med den testen vi nå har i 				&lt;code&gt;extend&lt;/code&gt; så kan vi trygt utvide 				&lt;code&gt;HTMLElement.prototype&lt;/code&gt; for nettlesere som støtter det - elementene vil ikke bli dobbeltutvidet alikevel.
&lt;/p&gt;

&lt;p&gt;
Å legge til tilsvarende funksjonalitet på 				&lt;code&gt;HTMLElement.prototype&lt;/code&gt; er heldigvis ganske simpelt og kan øke ytelsen på løsningen vår betraktelig. Utvidelsen er akkurat som andre utvidelser: vi skal utvide et objekt - i dette tilfellet 				&lt;code&gt;HTMLElement.prototype&lt;/code&gt; - med et sett med egenskaper:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;cj.Element.extend(HTMLElement.prototype);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Denne løsningen byr kun på ett problem:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var args = [element];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Når vi utvider prototypen er det prototypen som er 				&lt;code&gt;element&lt;/code&gt;, mens elementet er tilgjengelig som 				&lt;code&gt;this&lt;/code&gt; (fordi vi nå opererer i konteksten til prototypen til HTMLElement). Dette kan vi løse for begge tilfeller med en kondisjonell tilordning:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var args = [this instanceof Element ? this : element];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test8.html&quot;&gt;Kjør testene&lt;/a&gt;.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17086_8&quot;&gt;Final touches&lt;/h2&gt;
&lt;p&gt;
Vel, da var vi nesten i mål. Vi mangler nå bare den karakteristiske signaturen:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;test$: function() {
    var assert = YAHOO.util.Assert;
    var sample3 = $(&amp;quot;sample3&amp;quot;);
    assert.isNotUndefined(sample3.hasClassName);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Som kan implementeres relativt smertefritt:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;if (!window.$) {
    window.$ = cj.Element.get;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Legg merke til at vi er defensive nok til å passe oss for å overskrive eventuelt eksisterende dollar-funksjoner.
&lt;/p&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/dollar/test9.html&quot;&gt;Kjør hele testcaset&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Dette kan være et svært nyttig lite verktøy på mindre prosjekter der mengden kode ikke tilsier at man trenger et helt rammeverk. Uansett er det en morsom øvelse å implementere.
&lt;/p&gt;

&lt;p&gt;
Håper noen fant dette interessant. Vel møtt i morgen for en titt på kjeding av metodekall.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>16 Dec 2008 09:36:26 GMT</pubDate>
  <title>Testing av ytelse</title>
  <link>http://www.cjohansen.no/javascript/testing_av_ytelse</link>
  <guid>http://www.cjohansen.no/javascript/testing_av_ytelse</guid>
  <comments>http://www.cjohansen.no/javascript/testing_av_ytelse#comments</comments>
  <description>
    
&lt;p&gt;
Idag skal vi se på hvordan vi kan legge inn krav til ytelse som en del av testcasene våre.
&lt;/p&gt;

    
&lt;p&gt;
I går snakket vi om memoisering, og så hvordan spesielt Fibonacci-metoden ble betraktelig raskere. Faktisk gjorde vi mer enn det; vi gjorde det mulig å faktisk kjøre den for verdier stort større enn 20/30 (den opprinnelige løsningen møter fort veggen). Fin ytelse er vel og bra, men hvordan kan vi synliggjøre dette?
&lt;/p&gt;
	&lt;h2 id=&quot;toc17076_1&quot;&gt;Test, sett krav!&lt;/h2&gt;
&lt;p&gt;
Minimumskrav for ytelse er kvalitetskrav på lik linje med andre formelle krav vi stiller til koden vår. Det er ingenting i veien for å inkludere tester som krever et minimum av ytelse. Til nettopp dette foreslår jeg følgende assertion til jsunittest.js:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;JsUnitTest.Unit.Assertions.assertFasterThan = function(requirement, code, message) {
    var start = new Date();
    code.call();
    var elapsed = new Date() - start;
    message = this.buildMessage(message || 'assertFasterThan',
                                'expected to be faster than &amp;lt;?&amp;gt;ms, spent &amp;lt;?&amp;gt;ms', requirement, elapsed);

    this.assertBlock(message, function() { return elapsed &amp;lt; requirement; });
}

var unit = JsUnitTest.Unit;
unit.Testcase.prototype.assertFasterThan = unit.Assertions.assertFasterThan;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Dette er en assertion som kan brukes for å sjekke at et stykke kode ikke bruker mer enn spesifisert antall miliskunder på å kjøre. Gjør den det får vi en feil i enhetstesten, og koden ansees som ødelagt. La oss ta tak i den opprinnelige fibonacci-implementasjonen, og sette et krav til ytelse på denne. Å beregne fibonacci for &lt;i&gt;n=20&lt;/i&gt; burde ikke ta mer enn 5 ms:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testFibonacciPerformance: function() { with(this) {
    assertFasterThan(5, function() { fibonacci(20); });
}}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test5.html&quot;&gt;Kjører vi testen&lt;/a&gt; oppdager vi at implementasjonen slettes ikke er &amp;quot;up to it&amp;quot;. Sannsynligvis vil du få beskjed om at den ligger på ca 18ms. Ikke bra. Hva så med den alternative løsningen som cacher verdiene?
&lt;/p&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test6.html&quot;&gt;Testene&lt;/a&gt; tilsier at vår &amp;quot;fibonacci on steroids&amp;quot; ikke har noe problem med å benke dette kravet. Yay!
&lt;/p&gt;

&lt;p&gt;
Når du legger inn krav til ytelse i testene dine på denne måten er det viktig å legge inn grenser som tar høyde for at tiden det tar å kjøre et stykke kode kan variere relativt mye (mer jo raskere kodesnutter det er snakk om). I tillegg er det en del problemer med måling av korte tidsintervaller i nettlesere. John Resig (jQuery) skrev nylig en svært nyttig artikkel om akkurat dette:
&lt;/p&gt;
			
								
											
			&lt;blockquote title=&quot;John Resig om nøyaktighet i JavaScript-tid&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; cite=&quot;http://ejohn.org/blog/accuracy-of-JavaScript-time/&quot;&gt;
&lt;ol&gt;

&lt;li&gt; Any test that takes less than 15ms will always round down to 0ms in these browsers. It becomes impossible to determine how much time the tests are taking with consistently zeroed out results.&lt;/li&gt;

&lt;li&gt; The error rate for any test run in these browsers would be huge. If you had a simple test that ran in under 15ms the error rate would be a whopping 50-750%! You would need to have tests running for, at least, 750ms before you could safely reduce the error overhead of the browser to 1%. That's insane, to say the least.&lt;/li&gt;

&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;b&gt;Dette vil i praksis si at testen jeg serverte som eksempel over ikke vil være riktig på Windows.&lt;/b&gt; Dersom oppførsel spriker fra påstått oppførsel for dere som bruker Windows så gi gjerne beskjed! Det var uansett prinsippet og ikke de konkrete tallene som var poenget her. Man kan komme rundt slike ved å eksempelvis kjøre koden flere ganger og teste mot akumulert tid:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testFibonacciPerformance: function() { with(this) {
    assertFasterThan(50, function() {
        for (var i = 0; i &amp;lt; 10; i++) {
            fibonacci(20);
        }
    });
}}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Det var dagens korte JavaScript-tips. I morgen kjører vi en lengre tutorial med mye kode når vi ser på de populære &amp;quot;dollarfunksjonene&amp;quot;.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>15 Dec 2008 00:00:58 GMT</pubDate>
  <title>Memoisering av funksjoner</title>
  <link>http://www.cjohansen.no/javascript/memoisering_av_funksjoner</link>
  <guid>http://www.cjohansen.no/javascript/memoisering_av_funksjoner</guid>
  <comments>http://www.cjohansen.no/javascript/memoisering_av_funksjoner#comments</comments>
  <description>
    
&lt;p&gt;
Noen ganger trenger vi kode som forgreiner seg basert på objekters tilstand, nettleserens ferdigheter eller andre omstendigheter - omstendigheter som kan være krevende ytelsesmessig. Memoisering kan i slike tilfeller ofte by på forenkling av logikk og/eller bedre ytelse.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17066_1&quot;&gt;Memoisering?&lt;/h2&gt;			
								
											
			&lt;blockquote title=&quot;Wikipedia om memoisering&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; cite=&quot;http://en.wikipedia.org/wiki/Memoization&quot;&gt;
&lt;p&gt;
In computing, memoization is an optimization technique used primarily to speed up computer programs by having function calls avoid repeating the calculation of results for previously-processed inputs.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Memoisering er kort sagt caching på metodenivå.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17066_2&quot;&gt;Fibonacci&lt;/h2&gt;
&lt;p&gt;
I matematikken er 			
									
												
			&lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;Fibonacci-tallene&lt;/a&gt; kjent som en tallrekke der første tall er 0, andre tall er 1 og påfølgende tall er gitt som summen av de to foregående tallene. Med andre ord (uttrykt som en enhetstest med jsunittest.js):
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;new Test.Unit.Runner({
    testFibonacci: function() { with(this) {
        assertEqual(0, fibonacci(0));
        assertEqual(1, fibonacci(1));
        assertEqual(1, fibonacci(2));
        assertEqual(2, fibonacci(3));
        assertEqual(3, fibonacci(4));
        assertEqual(6765, fibonacci(20));
    }}
}, { testLog: &amp;quot;testlog&amp;quot; });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test1.html&quot;&gt;Kjør test&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
For en illustrasjon av styrken ved memoisering kan vi implementere funksjonen 				&lt;code&gt;fibonacci(num)&lt;/code&gt; slik den er definert ovenfor: for et tall &lt;i&gt;n&lt;/i&gt;, returner det &lt;i&gt;n&lt;/i&gt;te tallet i Fibonacci-rekka.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;// Only for n &amp;gt;= 0
function fibonacci(n) {
    if (n === 0) {
        return 0;
    } else if (n === 1) {
        return 1;
    }

    return fibonacci(n - 1) + fibonacci(n - 2);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Denne metoden løser rekka rekursivt og gjør jobben (			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test2.html&quot;&gt;kjør suksessfull test&lt;/a&gt;). Men, den er langt fra optimal. En rask titt i &lt;b&gt;Firebug avslører at metoden kalles i alt 21.891 ganger for å løse 				&lt;code&gt;fibonacci(20);&lt;/code&gt;&lt;/b&gt;. Hva kommer dette av?
&lt;/p&gt;

&lt;p&gt;
For å forstå problemet kan vi tenke oss gjennom noen kjøringer:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;				&lt;code&gt;fibonacci(20)&lt;/code&gt; kaller rekursivt 				&lt;code&gt;fibonacci(19)&lt;/code&gt; og 				&lt;code&gt;fibonacci(18)&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;fibonacci(19)&lt;/code&gt; kaller rekursivt 				&lt;code&gt;fibonacci(18)&lt;/code&gt; og 				&lt;code&gt;fibonacci(17)&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;				&lt;code&gt;fibonacci(18)&lt;/code&gt; kaller rekursivt 				&lt;code&gt;fibonacci(17)&lt;/code&gt; og 				&lt;code&gt;fibonacci(16)&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;osv&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
Her ser vi fort at funksjonen vår gjør mye jobb om igjen. Når vi regner ut for &lt;i&gt;20&lt;/i&gt; gjør vi dette ved å først regne ut først for &lt;i&gt;19&lt;/i&gt;, deretter &lt;i&gt;18&lt;/i&gt;. Når 				&lt;code&gt;fibonacci(19)&lt;/code&gt; er regnet ut og vi skal begynne på 				&lt;code&gt;fibonacci(18)&lt;/code&gt; er dette tallet allerede regnet ut, men snarere enn å bruke det tidligere resultatet gjøres hele beregningen på nytt.
&lt;/p&gt;

&lt;p&gt;
Her kommer memoisering inn.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17066_3&quot;&gt;Memoisering via oppslagstabeller&lt;/h2&gt;
&lt;p&gt;
En oppslagstabell er blant de enkleste former for memoisering. Funksjonen har en intern oppslagstabell hvor den lagrer verdier før den returnerer. Før den beregner verdier på nytt sjekkes tabellen om verdien allerede er beregnet. En rask implementasjon i 				&lt;code&gt;fibonacci()&lt;/code&gt; gir noe ala:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;// Only for n &amp;gt;= 0
function fibonacci(n) {
    // Define global (and public) lookup table
    if (!fibonacci.numbers) {
        fibonacci.numbers = [0, 1];
    }

    // Return memoized value if it exists
    if (fibonacci.numbers[n] || n === 0) {
        return fibonacci.numbers[n];
    }

    fibonacci.numbers[n] = fibonacci(n - 1) + fibonacci(n - 2);
    return fibonacci.numbers[n];
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Denne 			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test3.html&quot;&gt;passerer fortsatt testene&lt;/a&gt; - ergo fungerer den - og &lt;b&gt;Firebug bekrefter at vi nå er nede i 39 kall og betraktelig bedre ytelse&lt;/b&gt;. Men nå har vi sølet sammen memoisering/cachelogikk og funksjonens egentlige virke - Fibonaccitall. Dessuten er oppslagstabellen offentlig tilgjengelig via 				&lt;code&gt;fibonacci.numbers&lt;/code&gt;, noe som ikke er så stilig.
&lt;/p&gt;

&lt;p&gt;
Noen tanker senere kommer vi opp med en løsning som er hakket mer elegant, og fordi den unngår å konstant sjekke om oppslagstabellen må defineres også er raskere:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;window.fibonacci = (function() {
    // Lookup table
    var lookup = [];

    // Calculate fibonacci number
    // Still only works correctly for positive ns
    function fibonacciNumber(n) {
        return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
    }

    // The public function
    return function(num) {
        // Check cache
        if (typeof lookup[num] !== &amp;quot;undefined&amp;quot;) {
            return lookup[num];
        }

        // Cache empty, calculate value, update cache, return
        return (lookup[num] = fibonacciNumber(num));
    };
})();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/memoisering_av_funksjoner/test4.html&quot;&gt;Testene kjører stadig&lt;/a&gt;. Her ser vi også praktisk bruk av den anonyme funksjonen som kjøres umiddelbart for å lage en closure. Jeg har i tillegg dratt nytte av at returverdien er &lt;i&gt;n&lt;/i&gt; når &lt;i&gt;n&lt;/i&gt; er 0 eller 1.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17066_4&quot;&gt;Memoisering ved definering av funksjon&lt;/h2&gt;
&lt;p&gt;
En annen måte å øke ytelsen på kan være å unngå komplisert forgreiningslogikk (eller triviell forgreiningslogikk som kanskje kjøres &lt;b&gt;mye&lt;/b&gt;). 
&lt;/p&gt;

&lt;p&gt;
Et kremeksempel på dette er &amp;quot;Ajax&amp;quot;-objektet, 				&lt;code&gt;XMLHttpRequest&lt;/code&gt;, som finnes i en rekke varianter, avhengig av nettleser. Vanligvis abstraheres dette på følgende måte (			
											
			&lt;a href=&quot;http://ajaxcookbook.org/xmlhttprequest/&quot; hreflang=&quot;en&quot;&gt;via&lt;/a&gt;):
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function createXMLHttpRequest() {
    if (typeof XMLHttpRequest != &amp;quot;undefined&amp;quot;) {
        return new XMLHttpRequest();
    } else if (typeof ActiveXObject != &amp;quot;undefined&amp;quot;) {
        return new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);
    } else {
        throw new Error(&amp;quot;XMLHttpRequest not supported&amp;quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Vel og bra, men nettleseren forandrer seg strengt tatt ikke så lenge scriptet er lastet. En mer effektiv måte å gjøre dette på er å sjekke på forhånd hva nettleseren støtter for deretter å definere metoden:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;window.createXMLHttpRequest = (function() {
    if (typeof XMLHttpRequest != &amp;quot;undefined&amp;quot;) {
        return function() {
            return new XMLHttpRequest();
        };
    } else if (typeof ActiveXObject != &amp;quot;undefined&amp;quot;) {
        return function() {
            return new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);
        };
    } else {
        return function() {
            throw new Error(&amp;quot;XMLHttpRequest not supported&amp;quot;);
        };
    }
})();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Her har vi flytta om på forgreiningslogikken slik at den kjøres kun én gang per sidevisning, fremfor en gang hver gang vi oppretter et XHR-objekt.
&lt;/p&gt;

&lt;p&gt;
Hvis vi vil være skikkelig fine på det kan vi klage på at denne løsningen kjører forgreiningen én gang uansett om vi spør etter et XHR-objekt eller ikke. Dette kan også fikses ved å redefinere metoden første gang den kalles:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;window.createXMLHttpRequest = function() {
    if (typeof XMLHttpRequest != &amp;quot;undefined&amp;quot;) {
        // Redefine method
        window.createXMLHttpRequest = function() {
            return new XMLHttpRequest();
        };
    } else if (typeof ActiveXObject != &amp;quot;undefined&amp;quot;) {
        // Redefine method
        window.createXMLHttpRequest = function() {
            return new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);
        };
    } else {
        // Redefine method
        window.createXMLHttpRequest = function() {
            throw new Error(&amp;quot;XMLHttpRequest not supported&amp;quot;);
        };
    }

    // Run redefined method. This will only happen one time -
    // before the method redefines itself
    return window.createXMLHttpRequest();
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Det beste fra to verdener!
&lt;/p&gt;

&lt;p&gt;
Dermed har vi sett på tre måter å gjøre memoisering i JavaScript: med oppslagstabell, ved å &amp;quot;if-e&amp;quot; definisjonen av metoden, og ved å redefinere metoden fra metoden selv, første gang den kjøres.
&lt;/p&gt;

&lt;p&gt;
I morgen skal vi se hvordan vi kan synliggjøre slike forbedringer i enhetstestene våre.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>14 Dec 2008 12:44:40 GMT</pubDate>
  <title>Objektorientering via closures</title>
  <link>http://www.cjohansen.no/javascript/objektorientering_via_closures</link>
  <guid>http://www.cjohansen.no/javascript/objektorientering_via_closures</guid>
  <comments>http://www.cjohansen.no/javascript/objektorientering_via_closures#comments</comments>
  <description>
    
&lt;p&gt;
Som en praktisk applikasjon av closures ser vi på hvordan vi med hjelp av closures kan gi objektene våre en ekstra dimensjon.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17056_1&quot;&gt;Et simpelt objekt&lt;/h2&gt;
&lt;p&gt;
Med konstruktører initierer vi nye objekter med 				&lt;code&gt;new&lt;/code&gt; foran kallet til konstruktøren. Med objektliteraler kan vi lage nye objekter simpelthen via 				&lt;code&gt;{ property: &amp;quot;value&amp;quot; }&lt;/code&gt;. Vi kan også lage objekter som lagrer sin tilstand i en closure. Slike objekter lager vi enkelt nok ved å kalle en funksjon.
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function person(name, email) {
    var firstName, lastName;

    var personObj =  {
        getName: function() {
            return firstName + (!!lastName ? &amp;quot; &amp;quot; + lastName : &amp;quot;&amp;quot;);
        },

        setName: function(newName) {
            if (typeof newName === &amp;quot;undefined&amp;quot; || newName === null) {
                throw new TypeError(&amp;quot;Cannot set name without name&amp;quot;);
            }

            newName = newName.split(&amp;quot; &amp;quot;);
            firstName = newName.shift();
            lastName = newName.shift();
        },

        getEmail: function() {
            return email;
        }
    };

    personObj.setName(name);

    return personObj;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Denne funksjonen returnerer et nytt objekt som har tre metoder: 				&lt;code&gt;getName()&lt;/code&gt;, 				&lt;code&gt;setName(name)&lt;/code&gt; og 				&lt;code&gt;getEmail()&lt;/code&gt;. Det som skiller dette objekter fra &amp;quot;vanlige&amp;quot; objekter er at det hverken i objektliteralen eller andre steder er satt noen 				&lt;code&gt;name&lt;/code&gt;- eller 				&lt;code&gt;email&lt;/code&gt;-properties.
&lt;/p&gt;

&lt;p&gt;
Det som er spesielt interessant med dette er at closuren - altså det lokale skopet til 				&lt;code&gt;person&lt;/code&gt; - ikke er tilgjengelig for kode utenfor dette skopet. Prøv å bruke koden over:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var christian = person(&amp;quot;Christian Johansen&amp;quot;, &amp;quot;cj@cjohanseeen.no&amp;quot;);
console.log(christian.name); // undefined
console.log(christian.getName()); // &amp;quot;Christian Johansen&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Det er i det hele tatt ikke mulig å vite noe om den indre tilstanden til personobjekter. Implementasjonsdetaljer som at navn lagres som fornavn og etternavn skjules for omverdenen ved at medlemmene lagres i closuren som skapes av funksjonen 				&lt;code&gt;person&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Denne måten å lage objekter på gir oss med andre ord noe JavaScript ikke eksplisitt støtter: tilgangskontroll&lt;/b&gt;. Det er to nivåer med tilgang som kan defineres: privat eller offentlig (public). I tillegg er det vanlig å notere seg at man har &amp;quot;privilegerte metoder&amp;quot; - altså metoder som er public, men som aksesserer privat data (følgelig kan man også lage public metoder som ikke har tilgang på privat tilstand).
&lt;/p&gt;

&lt;p&gt;
Følgende gir en oversikt over hvor du kan definere hva:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&amp;quot;mitt.navnerom&amp;quot;.namespace() = function() {
    // Private variable
    var prop1, prop2;

    // Private metoder
    function meth1() {
    }

    return {
        // Public medlemmer
        prop3: null,
        prop4: null,

        // Public metoder
        meth2: function() {
        },

        // Priviligerte metoder
        meth3: function() {
            return prop1;
        }
    };
};&lt;/code&gt;&lt;/pre&gt;
	&lt;h2 id=&quot;toc17056_2&quot;&gt;What's the catch?&lt;/h2&gt;
&lt;p&gt;
Ved å opprette objekter på denne måten oppnår vi elegant skjuling av implementasjonsdetaljer, &lt;b&gt;men&lt;/b&gt; det er ikke gratis. Når vi lager objekter fra konstruktører har vi muligheten til å:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Definere konstruktør&lt;/li&gt;

&lt;li&gt;Legge funksjonalitet/standardverdi for properties på konstruktørens prototype&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Sistnevnte gir en potensielt stor besparing i minnebruk ettersom objekter kun har en property dersom den overskriver standardverdien. I tillegg er alle metodene lagret kun en gang - på konstruktørens prototype. Dette i kontrast mot &amp;quot;closure-objektene&amp;quot;, der &lt;b&gt;metoder er definert på samtlige instanser&lt;/b&gt;. Dette siste poenget er viktig.
&lt;/p&gt;

&lt;p&gt;
For å stikke fingeren i været sammenlignet jeg eksempelet over med dette:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;function Person(name, email) {
    this.setName(name);
        this.email = email;
    }

    Person.prototype = {
        firstName: &amp;quot;&amp;quot;,
        lastName: &amp;quot;&amp;quot;,

        getName: function() {
            return this.firstName + (!!this.lastName ? &amp;quot; &amp;quot; + this.lastName : &amp;quot;&amp;quot;);
        },

        setName: function(newName) {
            if (typeof newName === &amp;quot;undefined&amp;quot; || newName === null) {
                throw new TypeError(&amp;quot;Cannot set name without name&amp;quot;);
            }

            newName = newName.split(&amp;quot; &amp;quot;);
            this.firstName = newName.shift();
            this.lastName = newName.shift();
        },

        getEmail: function() {
            return this.email;
        }
};&lt;/code&gt;&lt;/pre&gt;
	&lt;h3 id=&quot;toc17056_2_1&quot;&gt;Måling&lt;/h3&gt;
&lt;p&gt;
Jeg er absolutt ingen ekspert på måling av minneforbruk i JavaScript, og på tidspunktet hadde jeg heller ikke Chrome (og dens tasktray) tilgjengelig. Jeg målte på følgende måte:
&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;Laget en side som opprettet 20.000 objekter via closures-metoden&lt;/li&gt;

&lt;li&gt;Åpnet Opera med denne siden&lt;/li&gt;

&lt;li&gt;Noterte minneforbruk for Opera&lt;/li&gt;

&lt;li&gt;Lukket siden og stengte nettleseren&lt;/li&gt;

&lt;li&gt;Gjentok eksperimentet for konstruktør-metoden&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;
Hvorvidt dette er en holdbar måte å måle på vet jeg ikke, men det gir i det minste en slags pekepinn. Stemmer det indikerer testene mine ca 36% forbedring ved å bruke konstruktør og prototype fremfor closures. Dette betyr ikke at du aldri skal bruke closures som skissert her, men at du bør tenke før du gjør det.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen for en diskusjon av memoisering av funksjoner.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>13 Dec 2008 12:33:21 GMT</pubDate>
  <title>Navnerom</title>
  <link>http://www.cjohansen.no/javascript/navnerom</link>
  <guid>http://www.cjohansen.no/javascript/navnerom</guid>
  <comments>http://www.cjohansen.no/javascript/navnerom#comments</comments>
  <description>
    
&lt;p&gt;
Fordi all JavaScript i utgangspunktet kjører i det globale skopet er det skremmende stor sjanse for kollisjoner mellom script (særlig om de er fra forskjellige kilder). Ved å bruke objekter som navnerom kan vi minimere scriptenes globale fotspor samtidig som vi kan beholde et rikt spekter av funksjonalitet.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17046_1&quot;&gt;Navnerom i JavaScript&lt;/h2&gt;
&lt;p&gt;
JavaScript tilbyr ingen formelle navnerom eller pakkeløsninger for koden din. JavaScript tilbyr et globalt nivå og lar det være opp til deg hvordan du vil skrive koden din. Sånt blir det fort søl i det globalenavnerommet av, men vi kan løse det ganske enkelt.
&lt;/p&gt;

&lt;p&gt;
Et &amp;quot;navnerom&amp;quot; er bare en eller annen måte å bygge koden i hierarkier fremfor å legge alt side-ved-side på samme nivå. I JavaScript gjøres dette med objekter:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var cj = {};

cj.Element = {
    // Element-relatert funksjonalitet
};

cj.Element.Event = {
    // Event-spesifikk element-funksjonalitet
};

cj.Tools = {};
cj.Tools.Remote = {};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
En fordel med koden over er at den &lt;b&gt;kun bidrar med ett eneste objekt i det globale navnerommet: 				&lt;code&gt;cj&lt;/code&gt;&lt;/b&gt;.
&lt;/p&gt;

&lt;p&gt;
I 			
											
			&lt;a href=&quot;http://www.validatious.org&quot; hreflang=&quot;en&quot;&gt;Validatious&lt;/a&gt; finnes det en haug med objekter; 				&lt;code&gt;Form&lt;/code&gt;, 				&lt;code&gt;Validator&lt;/code&gt;, 				&lt;code&gt;Fieldset&lt;/code&gt; og mye annet. Sjansen for at jeg er alene om klasser ved disse generiske navnene er små, og derfor er all kode &amp;quot;namespacet&amp;quot; i 				&lt;code&gt;v2&lt;/code&gt;-modulen, så det heller heter 				&lt;code&gt;v2.Form&lt;/code&gt; osv. Sjansene for kollisjon med andres kode er dermed langt mindre.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17046_2&quot;&gt;				&lt;code&gt;namespace()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;
Et navnerom er bare objekter i objekter. Noen ganger er objektene i de forskjellige nivåene nyttige objekter med &amp;quot;egen&amp;quot; funksjonalitet, og noen ganger er de bare tomme skall.
&lt;/p&gt;

&lt;p&gt;
Når du jobber med større prosjekter og deler funksjonalitet over flere filer kan det fort bli uklart hvilke navnerom som er tilgjengelige hvor. Og noen ganger skal du lage navnerom som nøster mer enn ett nivå lengre enn det du allerede har. I begge disse tilfellene kan det være nyttig å ha en funksjon som tar en streng og garanterer at navnerommet den definerer eksisterer - enten ved å bekrefte at det gjør det, eller ved å lage tomme objekter der de mangler.
&lt;/p&gt;

&lt;p&gt;
La oss spesifisere funksjonalitet med noen YUI Test-tester:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testExistingNameSpace: function() {
    var assert = YAHOO.util.Assert;

    // Make sure namespace &amp;quot;cj&amp;quot; is global
    window.cj = {};
    var namespace = &amp;quot;cj&amp;quot;.namespace();
    assert.isNotNull(namespace);
    assert.areEqual(cj, namespace);

    window.cj.Tools = { BrowserTools: {} };
    namespace = &amp;quot;cj.Tools.BrowserTools&amp;quot;.namespace();
    assert.isNotNull(namespace);
    assert.areEqual(cj.Tools.BrowserTools, namespace);
},

testNewNamespace: function() {
    var assert = YAHOO.util.Assert;

    assert.isUndefined(window.myns);
    var namespace = &amp;quot;myns.deeply.nested.namespace&amp;quot;.namespace();
    assert.isNotNull(myns);
    assert.isNotNull(myns.deeply.nested.namespace);
},

testSeparator: function() {
    var assert = YAHOO.util.Assert;

    assert.isUndefined(window.separatorNS);
    var namespace = &amp;quot;separatorNS-nest-some&amp;quot;.namespace(&amp;quot;-&amp;quot;);
    assert.isNotNull(namespace);
},

testPreserveExisting: function() {
    var assert = YAHOO.util.Assert;
    window.cj = { Tools: { BrowserTools: { version: &amp;quot;1.0&amp;quot; } } };
    var namespace = &amp;quot;cj.Tools&amp;quot;.namespace();

    assert.isNotNull(cj.Tools.BrowserTools);
    assert.areEqual(cj.Tools, namespace);
    assert.areEqual(&amp;quot;1.0&amp;quot;, namespace.BrowserTools.version);
},

testAssignToNewNamespace: function() {
    var assert = YAHOO.util.Assert;
    &amp;quot;cj.Namespace.Test&amp;quot;.namespace().version = &amp;quot;2.0&amp;quot;;
    assert.isNotUndefined(cj);
    assert.isNotUndefined(cj.Namespace);
    assert.areEqual(&amp;quot;2.0&amp;quot;, cj.Namespace.Test.version);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/navnerom/test1.html&quot;&gt;Testene feiler&lt;/a&gt;, som de skal når vi ikke har koda noe enda. Fra testene vet vi at koden skal:
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Ligge i 				&lt;code&gt;String.prototype&lt;/code&gt;, så den kan kjøres rett på strenger&lt;/li&gt;

&lt;li&gt;Ta en valgfri parameter - skilletegnet - som default er punktum&lt;/li&gt;

&lt;li&gt;Ikke overskrive eksisterende objekter&lt;/li&gt;

&lt;li&gt;Metoden må returnere navnerom-objektet slik at metodekallet kan brukes som et vanlig objekt&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;
Og med det hacker vi i vei:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;String.prototype.namespace = function(separator) {
    // Optional parameter
    separator = separator || &amp;quot;.&amp;quot;;

    // Initial scope
    var scope = window;

    // Individual pieces
    var objects = this.split(separator);

    for (var i = 0, object; (object = objects[i]); i++) {
        // Note: object[&amp;quot;property&amp;quot;] === object.property
        if (typeof scope[object] === &amp;quot;undefined&amp;quot;) {
            scope[object] = {};
        }

        scope = scope[object];
    }

    return scope;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/navnerom/test2.html&quot;&gt;Testene gir oss den gode følelsen når de blir grønne&lt;/a&gt;. Merk at implementasjonen er en minimumsløsning i forhold til kravene (testene). Heldigvis gir den allikevel grei håndtering av forskjellige strenger, noe denne testen gir et hint om:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;testBogusInput: function() {
    var assert = YAHOO.util.Assert;

    var namespace = &amp;quot;&amp;quot;.namespace();
    assert.areEqual(window, namespace, &amp;quot;Implicit namespace should be global namespace&amp;quot;)

    namespace = &amp;quot;.&amp;quot;.namespace();
    assert.areEqual(window, namespace, &amp;quot;Bogus namespace should yield global namespace&amp;quot;)
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/navnerom/test3.html&quot;&gt;Denne passerer&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
YUI har forøvrig 			
											
			&lt;a href=&quot;http://developer.yahoo.com/yui/yahoo/#namespace&quot; hreflang=&quot;en&quot;&gt;en lignende metode&lt;/a&gt;, men som namespacer ting inn i 				&lt;code&gt;YAHOO&lt;/code&gt;-objektet.
&lt;/p&gt;

&lt;p&gt;
Vel møtt i morgen for en gjennomgang av objektorientering med closures.
&lt;/p&gt;

  </description>
</item>
            <item>
  <pubDate>12 Dec 2008 00:01:41 GMT</pubDate>
  <title>Prototyper og JavaScripts innebygde typer</title>
  <link>http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer</link>
  <guid>http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer</guid>
  <comments>http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer#comments</comments>
  <description>
    
&lt;p&gt;
Ved hjelp av JavaScripts prototype-kjeder kan vi bygge funksjonalitet inn i objekter vi ikke selv har laget - så også JavaScripts innebygde objekter. Vi ser på hvordan dette gjøres og noen nyttige applikasjoner.
&lt;/p&gt;

    	&lt;h2 id=&quot;toc17036_1&quot;&gt;Prototyper&lt;/h2&gt;
&lt;p&gt;
Som forklart både i et tidligere innlegg om 			
									&lt;a href=&quot;/javascript/objektorientert_javascript&quot;&gt;objektorientering i JavaScript&lt;/a&gt;, og tidligere i julekalenderen har alle JavaScript-objekter en prototype - et objekt de er basert på. For eksempel er alle strenger basert på 				&lt;code&gt;String.prototype&lt;/code&gt;. Et objekts prototype er &lt;i&gt;på en måte&lt;/i&gt; tilsvarende en klasse - men husk at &lt;b&gt;en prototype er et objekt, ikke en klasse&lt;/b&gt; (jada, klasser kan være objekter, men JavaScript har ikke klasser).
&lt;/p&gt;
	&lt;h2 id=&quot;toc17036_2&quot;&gt;				&lt;code&gt;trim()&lt;/code&gt; igjen&lt;/h2&gt;
&lt;p&gt;
Tidlig i kalenderen laget vi en 				&lt;code&gt;trim&lt;/code&gt;-funksjon som trimmet innledende og avsluttende whitespace i en streng. Idag gjør vi den objektorientert, sånn at det blir 				&lt;code&gt;&amp;quot; min streng &amp;quot;.trim();&lt;/code&gt; i stedet for 				&lt;code&gt;trim(&amp;quot; min streng &amp;quot;);&lt;/code&gt;. La oss oppdatere testcaset fra sist:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;new Test.Unit.Runner({
    testTrimTrailingSpace: function() { with(this) {
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot;Streng &amp;quot;.trim(),
                    &amp;quot;Trailing space should be removed&amp;quot;);
    }},

    testTrimLeadingSpace: function() { with(this) {
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot; Streng&amp;quot;.trim(),
                    &amp;quot;Leading space should be removed&amp;quot;);
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot;Streng   &amp;quot;.trim(),
                    &amp;quot;All trailing spaces should be removed&amp;quot;);
    }},

    testNoTrimInnerSpace: function() { with(this) {
        var sentence = &amp;quot;A complete sentence with     lots of whitespace.&amp;quot;;
        assertEqual(sentence, sentence.trim(),
                    &amp;quot;Inner space should not be removed&amp;quot;);
    }},

    testTrimTrailingAndLeadingSpace: function() { with(this) {
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot; Streng &amp;quot;.trim(),
                    &amp;quot;Both leading and trailing space should be removed&amp;quot;);
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot;   Streng   &amp;quot;.trim(),
                    &amp;quot;All leading and trailing spaces should be removed&amp;quot;);
    }},

    testTrimAnyWhiteSpace: function() { with(this) {
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot; \n\t Streng&amp;quot;.trim(),
                    &amp;quot;Any kind of whitespace should be trimmed&amp;quot;);
        assertEqual(&amp;quot;Streng&amp;quot;, &amp;quot;   Streng\n&amp;quot;.trim(),
                    &amp;quot;Trailing newlines should be trimmed&amp;quot;);
    }}
}, { testLog: &amp;quot;testlog&amp;quot; });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer/test1.html&quot;&gt;Kjør testen&lt;/a&gt;, og observer at den feiler.
&lt;/p&gt;
	&lt;h3 id=&quot;toc17036_2_1&quot;&gt;Hvordan få fatt i prototypen?&lt;/h3&gt;
&lt;p&gt;
Det er ingen måte å få tak i et objekts prototype direkte (foruten 				&lt;code&gt;__proto__&lt;/code&gt;, som er en Firebug-feature). Derfor må vi vite hvordan prototypen settes for et objekt. Et objekt (kan) instansieres fra en konstruktør, og en konstruktør har en 				&lt;code&gt;prototype&lt;/code&gt;-egenskap som definerer prototypen for nye objekter som instansieres fra denne konstruktøren. Puh!
&lt;/p&gt;

&lt;p&gt;
Strenger kommer fra 				&lt;code&gt;String&lt;/code&gt;-konstruktøren. La oss gjøre et eksperiment: hente en metode på prototypen og kalle den:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;console.log(typeof String); // &amp;quot;function&amp;quot;
console.log(typeof String.prototype); // &amp;quot;object&amp;quot;
console.log(typeof String.prototype.indexOf); // &amp;quot;function&amp;quot;
console.log(String.prototype.indexOf(&amp;quot;script&amp;quot;)); // -1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Ikke overraskende returnerte vårt forsøk på å finne første plassering av substrengen &lt;i&gt;script&lt;/i&gt; -1. Metodene på prototypen forventer at 				&lt;code&gt;this&lt;/code&gt; er et strengeobjekt. Heldigvis kan vi sette 				&lt;code&gt;this&lt;/code&gt; til hva som helst når vi bruker 				&lt;code&gt;call&lt;/code&gt; og 				&lt;code&gt;apply&lt;/code&gt;, så for å søke etter en substreng i en annen streng på en utradisjonell måte kan vi gjøre:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;console.log(String.prototype.indexOf.call(&amp;quot;JavaScript&amp;quot;, &amp;quot;script&amp;quot;)); // 4&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Voila!
&lt;/p&gt;
	&lt;h3 id=&quot;toc17036_2_2&quot;&gt;Flytte 				&lt;code&gt;trim()&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
Ok, da har vi klart å lese ut - og kjøre - noe fra prototypen til strenger. Siden alt er åpent i JavaScript kan vi også skrive til prototypen:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;String.prototype.trim = function(str) {
    return str.replace(/^\s+|\s+$/g, '');
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer/test2.html&quot;&gt;Dette feiler fullstendig&lt;/a&gt;. Hvorfor? Vel, når vi nå operer som en metode på strengens prototype fremfor en frittstående funksjon er det andre grep som må til for å få tak i strengen som skal vaskes. Som jeg forsøkte å forklare over, vil 				&lt;code&gt;this&lt;/code&gt; inne i metodene på prototypen alltid tilsvare et objekt av den aktuelle typen (i vårt tilfelle en streng). Altså må vi ta bort innparameteren og heller jobbe direkte på 				&lt;code&gt;this&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
			
									&lt;a href=&quot;http://www.cjohansen.no/javascript/prototyper_og_javascripts_innebygde_typer/test3.html&quot;&gt;Testene kjører&lt;/a&gt;, og vi kan trygt nyte en kaffe.
&lt;/p&gt;
	&lt;h2 id=&quot;toc17036_3&quot;&gt;Bruksområder&lt;/h2&gt;
&lt;p&gt;
Med denne kunnskapen i verktøykassa er det bare fantasien som stopper deg. Om du vil kan du legge inn all funksjonaliteten fra ditt favorittspråk i JavaScript, sånn at det ligner mer. Det er i praksis langt på vei dette 			
									
												
			&lt;a href=&quot;http://prototypejs.org&quot; lang=&quot;en&quot; xml:lang=&quot;en&quot; hreflang=&quot;en&quot;&gt;prototype.js&lt;/a&gt; har gjort - de har dratt JavaScript nærmere Ruby.
&lt;/p&gt;

&lt;p&gt;
MooTools legger også til funksjoner i de innebygde typene, se bare deres 			
											
			&lt;a href=&quot;http://mootools.net/docs/Native&quot; hreflang=&quot;en&quot;&gt;&amp;quot;Native&amp;quot;-dokumentasjon&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Et svært interessant bruksområde for dette er å legge til eller fikse (standardisert) funksjonalitet. Mozilla byr i sin 			
											
			&lt;a href=&quot;https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:forEach&quot; hreflang=&quot;en&quot;&gt;dokumentasjon av JavaScript 1.5&lt;/a&gt; på sin egen implementasjon av 				&lt;code&gt;Array.forEach()&lt;/code&gt; slik at man kan sørge for at nettlesere som ikke støtter denne får den definert:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(fun /*, thisp*/) {
        var len = this.length;

        if (typeof fun != &amp;quot;function&amp;quot;) {
            throw new TypeError();
        }

        var thisp = arguments[1];

        for (var i = 0; i &amp;lt; len; i++) {
            if (i in this) {
                fun.call(thisp, this[i], i, this);
            }
        }
    };
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Dette gir alle nettlesere muligheten til å loope arrays som dette:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;[9, 8, 7, 6, 5, 4, 3, 2, 1].forEach(function(element, index, array) {
    console.log(element);
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Vel møtt i morgen, når vi tar i bruk denne kunnskapen i en diskusjon om navnerom i JavaScript.
&lt;/p&gt;

  </description>
</item>
      </channel>
</rss>

