Ninjatriks i JavaScript, del 2

Jeg var ikke sikker på om det kom til å skje, men når jeg øynet muligheten til å kombinere mine to favoritthobbyer, koding og øl, måtte jeg jo bare. Dermed blir det del 2 av ninjatriks i JavaScript, denne gang med fokus på funksjonell programmering og underscore.js.

Ifølge Douglas Crockford er JavaScript “Lisp in C’s Clothing”. Dvs, det er et funksjonelt språk utkledd som et prosedyrespråk. De fleste som har skrevet litt JavaScript har funnet ut at det går fint å skrive prosedyre (og kanskje også objekt)-orientert i JavaScript.

Men, hvis det nå er sånn at JavaScript er funksjonelt så burde det kanskje være noe å hente? Jeg snakker ikke helt nazi no-sideeffects, everything is a function, men noen gode ideer her og der?

Det har ihvertfall jeg funnet ut de senere år, etter at jeg tok i bruk Backbone.js og dermed Underscore.js. Underscore.js er et lite utility-bibliotek som beskriver seg som “It’s the tie to go along with jQuery’s tux, and Backbone.js’s suspenders.”. Ja, mange av de funksjonene underscore.js tilbyr finnes som “native”-javascript funksjoner i nyere implementasjoner. Dog, jeg har lært meg underscore og trives med det, dermed så vil jeg fokusere på det.

Men, hva er det å hente? Hva gir underscore og en funksjonell tankegang meg? Jeg tenkte å ta noen eksempler, så kan du se selv.

Eksempel 1 er ganske greit. Du har ei liste med objekter (la oss si øl-objekter). Du vil finne alle objekter (dvs øl) som er produsert av Haandbryggeriet. Gitt lista (som tilfeldigvis er fra en juleølsmaking jeg deltok på):

    var beers = [
       {"brewery": "Austmann", "name": "Jingle Beer", "score": 6.49, "abv": 7},
        {"brewery": "Binding-Brauerei", "name": "Santa Clausthaler", "score": 2.14, "abv": 0},
        {"brewery": "Brasserie St-Feuillien", "name": "Cuvée de Noël", "score": 6.43, "abv": 9},
        {"brewery": "Dahls", "name": "Julebrygg", "score": 5.19, "abv": 4.5},
        {"brewery": "Fanø Bryghus", "name": "Julebryg", "score": 5.74, "abv": 7.2},
        {"brewery": "Grans Bryggeri", "name": "Lade Gaards Brygghus Juleøl", "score": 5.92, "abv": 6.5},
        {"brewery": "Hansa", "name": "Ekstra Vellagret Julebrygg", "score": 6.39, "abv": 6.5},
        {"brewery": "Haandbryggeriet", "name": "Nissefar", "score": 6.07, "abv": 7},
        {"brewery": "Haandbryggeriet", "name": "Nissegodt", "score": 6.26, "abv": 4.5},
        {"brewery": "Inderøy", "name": "Nisseøl", "score": 6.06, "abv": 4.5},
        {"brewery": "Nøgne Ø", "name": "God Jul", "score": 5.89, "abv": 8.5},
        {"brewery": "Nøgne Ø", "name": "Julesnadder", "score": 7.19, "abv": 4.5},
        {"brewery": "Nøgne Ø", "name": "Special Holiday Ale", "score": 6.71, "abv": 9},
        {"brewery": "Ægir", "name": "Julebrygg", "score": 6.21, "abv": 4.7}
    ];

Hvis vi nå vil finne ut hvilke som var butikkøl (dvs abv <= 4.7) kan du gjøre dette med en for-løkke:

    var pol_limit = 4.7;
    var shop_beers = [];
    for (var i = 0; i< beers.length; i++) {
        var beer = beers[i];
        if (beer.abv <= pol_limit) {
            shop_beers.push(beer);
        }
    }
    console.log(shop_beers);

Ganske standard, men mye boilerplate og unødvendige temporær-variabler. Hva med Underscore.js? Vi kan bruke _.filter():

var isShopBeer = function (beer) {
    return (beer.abv <= 4.7);
};
console.log(_.filter(beers, isShopBeer));

Det som skjer her er at _.filter() looper gjennom lista beers og returnerer en ny liste over de ølene som returnerer true i funksjonen isShopBeer. Ganske fiffig, færre linjer og lettere utbyttbart.

En annen artig ting, er at siden vi nå har en funksjon for å bestemme om et øl er butikkøl, vet vi at alle øl som returnerer false i denne er poløl. Dermed kan vi finne antall poløl ved å bruke _.reject():

console.log(_.reject(beers, isShopBeer));

Så, dermed kan vi finne ut at vi hadde:

var shopBeers = _.filter(beers, isShopBeer);
var polBeers = _.reject(beers, isShopBeer);

console.log("Antall øl: " + beers.length);
console.log("Antall butikkøl: " + shopBeers.length);
console.log("Antall poløl: " + polBeers.length);

eller:

  • Antall øl: 14
  • Antall butikkøl: 6
  • Antall poløl: 8

Hva om vi vil finne ut hvilket øl som gjorde det best? Og dårligst? Med en for-løkke kunne vi gjort dette som

var max = beers[0];
for(var i = 1; i max.score) {
        max = beer;
    }
}
console.log(max.name) //Julesnadder

Med underscore kan vi bruke _.max():

var getBeerScore = function(beer) {
    return beer.score;
}

console.log(_.max(beers, getBeerScore)); //Julesnadder

og tilsvarende har vi såklart _.min():

console.log(_.min(beers, getBeerScore).name); //Santa Clausthaler

Altså:

var best = _.max(beers, getBeerScore);
var worst = _.min(beers, getBeerScore);

console.log("Best: ", best.brewery + " " + best.name + " (" + best.score + "/10)");
console.log("Værst: ", worst.brewery + " " + worst.name + " (" + worst.score + "/10)");

eller:

  • Best: Nøgne Ø Julesnadder (7.19/10)
  • Værst: Binding-Brauerei Santa Clausthaler (2.14/10)

Best av polølene da? Typisk ville vi gjort noe sånt som:

var pol_limit = 4.7;
    var max = 0.0;
    var best;
    for (var i = 0; i< beers.length; i++) {
        var beer = beers[i];
        if (beer.abv > pol_limit && beer.score > max) {
            console.log(beer.name)
            best = beer;
            max = beer.score;
        }
    }
    console.log(best.name); //Special Holiday Ale

Men, vi kan kombinere underscore-funksjoner:

console.log(_.max(_.reject(beers, isShopBeer), getBeerScore)); //Special Holiday Ale

Hvor mange øl var det med fra hvert bryggeri?

Vel, en måte å løse det på er følgende:

var result = {};
for (var i = 0; i< beers.length; i++) {
    var beer = beers[i];
    if (result.hasOwnProperty(beer.brewery)) {
        result[beer.brewery] += 1;
    } else {
            result[beer.brewery] = 1;
    }
} 
console.log(result);

Med underscore kan vi bruke _.groupBy():

var getBrewery = function (beer) {
    return beer.brewery;
}
console.log(_.groupBy(beers, getBrewery))

denne gir oss riktignok en liste med øl-objekter på hver key, ikke bare antallet. Det kan vi dog få til med en _.reduce():

console.log(_.reduce(_.groupBy(beers, getBrewery), function (memo, beers, brewery) {
    memo[brewery] = beers.length;
    return memo;
},{}));

Men, det spørs om det er det vi egentlig vil? Med resultatet av groupBy'en kan vi spytte ut endel statistikk:

_.each(_.groupBy(beers, getBrewery), function (beers, brewery) {
    var avg_score = _.reduce(beers, function(sum, beer){ return sum + beer.score; }, 0) / beers.length;
    console.log(brewery + ": " + beers.length + " øl, " + avg_score + " i gj.snitt");
});

Vel, det var det for denne gang. Håper du lærte noe nytt, hvis du har spørsmål eller kommentarer er det bare å mase (jeg har sikkert gjort noen feil, jeg er på ingen måte noen mester, men jeg lærer stadig!)

Innovation at gunpoint

..eller hvorfor vi ikke ser resultater av Kartverkets datafrislipp (enda).

Norge Digitalt Teknologiforum sa Thomas Nordtvedt fra FAD følgende:

“nå er det en måned siden Kartverket slapp gratisdata, hvor er resultatene?” [fritt etter hukommelsen]

Jeg reagerte litt på dette og har i ettertid tenkt endel på det. For, hvorfor er det ikke sånn at nye, innovative tjenester og løsninger basert på de (nå frigjorte) kartdataene har poppet opp? Hvorfor ser vi ikke resultater? Her har de offentlige spyttet flerfoldige millioner [citation needed] i å frigjøre en rekke kartdata og så får vi ingen resultater? Fy og skam!

Vel, jeg mener det er en rekke årsaker til dette. De to viktigste er

  1. Tid
  2. Kunnskap

Tid
For å ta den første først: en måned (eller to) er ikke mye tid til å komme opp med en ny ide, lage planer, programmere og lansere. Det å lansere nye tjenester tar ofte endel tid, både når det gjelder å komme opp med faktiske ideer og ikke minst faktisk utvikle den. Hvis tanken er at “hobbynerder” skal komme opp med nye apper, websider og løsninger må man tenke på at disse (som regel?) har en “vanlig” jobb og (mer eller mindre) et sosialt liv. Dermed blir det kanskje et par-tre kvelder i uka man får satt av til hobbyprosjekter. Dette blir i sum kanskje 50-60 timer siden frislippet, som jeg av erfaring kan si at ikke er mye tid til å komme opp med og lage noe nytt på.

Når det gjelder etablerte programvarehus, konsulentselskaper og andre aktører høres jo 1-2 måneder mye ut. Dog, realiteten er at de som allerede er inne i markedet nok har tatt gratisdataene i bruk allerede (det sa vel Sverre Wisløff fra Norkart på Teknologiforum), men de nye løsningene har ikke kommet enda. Det de har gjort er å slutte å betale for dataene de allerede bruker (fordi de nå er gratis). WebAtlas fra Norkart er et god eksempel her. Når det gjelder andre aktører er det ikke slik at det til enhver tid sitter ledige utviklere klare til å hive seg over nye muligheter, det er en treghet i markedet, folk sitter på prosjekter og man må allokere tid for å gå i gang med noe nytt. Ellers gjelder nok en del av det jeg skriver under om kunnskap her også.

Kunnskap
Det andre punktet, kunnskap, er mangedelt. Først har vi kunnskapen om at dataene faktisk er tilgjngelige. Ja, det har vært noe medieoppslag og noe blæst rundt det, men jeg tror ikke den jevne hobbynerd har fått med seg så mye om frislippet. Et Google-søk på “gratis kartdata” gir riktignok Kartverkets nedlastingsside som første treff. Dog, det spørsmålet man må stille seg er hvem som finner på å søke etter “gratis kartdata”? Bruker ikke de fleste Google Maps uansett? OpenStreetMap? Her finnes bibliotekene, APIene og tutorialene. Det finnes svært få steder der en som ikke har filla snøring på norske kartdata (det være seg formater, konvensjoner, koordinatsystemer og andre særegenheter) kan lære seg å bruke disse dataene (hvis det finnes, si gjerne ifra!).

Dermed er det et tre-delt kunnskaps-problem: 1) folk vet ikke at dataene er der, 2) folk vet ikke hvordan de skal ta dataene i bruk (enten er det SOSI-filer, eller så er det kjempesvære geojson-filer som kræsjer en 3 år gammel laptop (min!). 3) folk vet ikke hva de kan gjøre med disse dataene, fordi de ikke har hatt mulighet til å leke med dem før.

Så. Det å slippe dataene sine fri og etter 1-2 måneder klage på at det ikke har, opp av det blå, dukket opp noen nye, innovative løsninger som forsvarer investeringen et slikt frislipp er, det er naivt. Ting Tar Tid, også i en verden med super-agile utviklere (etter “Petter Smarter”) som kan finne på å interessere seg for sære ting.

Så, er alt håp ute og frislippet en gedigen bommert og bortkasta skattepenger? Nei! For det første kan norske selskaper som allerede jobber med kartdata spare utgifter. De kan også tilby bedre data til sine brukere, noe som i seg selv er en gevinst. For det andre vil det, med tiden, dukke opp nye løsninger. Kartverket vil få tilbakemeldinger på sine data og kanskje rette opp feil.

Så, om noe tid, når det har blitt “allmennkunnskap” at offisielle, norske kartdata kan benyttes fritt vil det begynne å komme løsninger som kan kalles innovative og nyskapende og kanskje også tilføre noe verdier noe sted. Men, det å forvente at det sitter en haug nerder og hopper når staten sier “Hopp”, som hiver seg over de nye dataene uten noe skikkelig veiledning, oppmuntring eller use-case, det er naivt.

Jeg har selv lekt med tanken om å gjøre noe spennende med disse dataene, men jeg ble rett og slett litt negativ til hele greia når jeg oppfattet at det nesten _forventes_ at noe gjør noe med disse dataene. Dog, jeg tror ikke dette kommer til å stoppe meg helt, så følg med. Når inspirasjonen, ideene og tiden kommer skal jeg prøve å være innovativ med dem. Men, det er ikke fordi en statssekretær mener jeg skal være det, men fordi jeg selv har lyst!

Norge Digitalt Teknologiforum

Norge Digitalt er en sammenslutning av de som produserer kartdata her i landet (dvs kommunene, Kartverket og en rekke offentlige etater). En gang i året har visstnok denne gjengen et “teknologiforum”.

Av en eller annen grunn var det noen som mente jeg burde være med på dette (som jo er åpent for alle), og etter å ha sett på programmet mente jeg det samme.

Dermed ble jeg vekket av en telefon fra flytaxisjåføren 06.00, bråvåkna, kasta på meg klæra og befant meg på Lillestrøm 09.00, en time før showet starta. Endel kaffe og prat med andre fagfolk senere satt jeg klar for teknologiforum, uten helt å vite hva jeg gikk til. Kom jeg, som har ønsket SOSI-dotformatet dødt, til å bli ofret her på SOSI-presteskapets alter?

Heldigvis ble jeg ikke slaktet av hverken møteleder Kyrre eller assisterende kartverkssjef Knut Arne. Jeg ble (sammen med de rundt 100 andre oppmøtte) ønsket velkommen til teknologiforum, og følte meg igrunn veldig velkommen. Det ble vel nesten bedre da Thomas Nordtvedt fra FAD snakket om åpne data i Norge og EU og hvilke lover, regler og direktiver som gjelder dette. Det ble jo også endel snakk om det nye “superdepartementet”, hvor Kartverket skal flyttes inn, og såklart Difis rolle. Kort og godt ble tonen satt, her skal det ikke selges noe, det skal diskuteres, opplyses og tenkes.

En ting jeg reagerte på var at Nordtvedt sa at “nå er det en måned siden Kartverket slapp gratisdata, hvor er resultatene?” Tror jeg må skrive en egen bloggpost om dette, men kortversjonen er at du får ikke innovasjon på en måned!

Frem til lunsj fortsatte det i plenum, og vi var innom sikkerhet, partene i ND (mye lover, forskrifter og direktiver!) og KS/KommIT (IT i kommunene, spennende tema som burde oppta mange i ND).

Etter lunsj splittet vi oss i to sesjoner (eller arbeidsmøter). Jeg fikk høre mye om ny nasjonal geoportal, geoNorge. Både strakstiltak på den eksisterende og den nye portalen som man snart går i gang med. Absolutt spennende, det er ikke tvil om at det er mye som skal gjøres, så vi får håpe det går etter planen!

Etter en felles oppsummering var det halvannen time til middag. Jeg brukte et par min på å reflektere over hvor lite jeg hadde twitra (jeg ble vel også fortalt det av flere). Jeg lovte å opprette #NDTech og være mer aktiv på dag 2. Etter en time på øyet for å ta igjen det tapte var det middag. Der ble sosi-dotformatet diskutert mye, men i en hyggelig tone (jeg har jo begynt å like formatet litt ;) ).

En ny ting skjedde også, for første gang jeg kan huske tok jeg tidlig kvelden på en geomatikk-konferanse. Var det fordi alexanno ikke var der og ledet meg ut i fristelse? Eller fordi jeg ville være frisk og rask til dag 2?

Dag 2 startet i et fullstappet Hordaland (møterom, ikke fylke) og temaet for arbeidsmøtet var innovasjon. Som ung og dynamisk fyr med mye meninger måtte jo dette være noe for meg. Vi var innom innovasjon generelt, innovasjon i infrastruktur og vi fikk en rapport fra Norkarts pilgrimstur til junaiten. Etter en brukerhistorie om Kartverkets “rett i kartet”-løsning prøvde jeg å starte en debatt om open street map, men den nådde ikke SOSI-dotformat-tilstander. Til slutt fikk vi (eller i det minste jeg) et innblikk i sjøkartverket og hva de innoverer på. “Artig” detalj at nesten alle dataene vi fikk se var fra Svalbard (grunnet sikkerhetsbeatemmelser). På toppen av det hele rakk vi gjennom noen artige kart fra Sverre Wisløff og noen artige videoer.

Etter lunsj med nok en runde tekniske diskusjoner var det oppsummeringer av sesjonene, før Espen Andersen fra BI snakket om innovasjon. Jeg bet meg spesielt merke i det han sa om disruptive teknologier, jeg synes jeg ser en link til hvordan holdningen er (har vært?) til fri programvare og open street map, men det er kanskje bare meg? I det hele tatt et meget proft og godt foredrag!

Siste dame på podiet var Frøstrup, som oppsummerte, snakket litt om Paul Chaffey (han er visst en populær fyr) og konkluderte med at data må brukes (amen!). Teknologiforums rolle ble også trukket frem som viktig.

Så, hvordan var dette? Det var mer konferanse og mindre workshop enn jeg hadde trodd, men det var gode foredrag og det gikk mer i dybden enn Geomatikkdagene. Mye kjente fjes, men også endel nye bekjentskaper. Alt i alt er jeg veldig glad for at jeg tok turen, det skjer så mye i geomatikk-verdenen for tida, og å få dybde på endel ting var meget bra!

Jeg har også fått inspirasjon til et par nye bloggposter, så det kan fort være set kommer noe mer her på bloggen. En erfaring er at å provosere litt er gøy ;)

Hvem er vi?

Dette ble skrevet for en god stund siden, sendt inn til Posisjon, men tydligvis glemt. Tenkte at jeg i det minste kan legge det ut her.

Hvem er vi egentlig? Ja, vi, vi er jo geomatikere må vite. Vi jobber med kart. Og verden, eller i det minste Norge da, trenger flere av oss. Jeg ser også det. Jeg mener, det er jo så altfor få utviklere som kan kart. Alle klarer å sette opp en markør i Google Maps på ei nettiside, men hvis du spør dem om å legge inn en WMTS-service fra en tilecache og POSTe tilbake editerte polygoner vha WFS-t til PostGIS ser de dumt på deg! Hæ, ser du også dumt på meg? Men, dette er jo Posisjon, fagbladet for oss geomatikere! Her må jeg vel kunne snakke fag, uten å dumme det ned? Åja, landmåler sa du. Prismer og målinger og totalstasjoner og CPOS, var det det du sa? Snakk litt saktere, jeg skjønner ikke helt. Du gjør hva? Kjører landet rundt og ser inn i en kikkert? Og du er geomatiker??

Vel, jeg skal avslutte der før jeg virkelig avslører hullene i min kunnskap om geomatikkfaget (eller fagområdet?). Poenget mitt tror jeg uansett burde være klart: Vi er en ganske merkelig miks av mennesker vi geomatikere. Fellesnevneren er kart i Norge (ett poeng for selskapsnavn!), eller geodata (enda ett!) eller geomatikk (hat-trick!) da. Vi jobber med så forskjellige ting som oppmåling ute i allslags vær, byggeplasser og fastpunkter utenfor alfarvei til det trygge kontormiljøet. Og hva gjør vi i kontormiljøet? Vel, jeg skriver kode, andre holder rede på SOSI-koder mens atter andre jobber med matrikkelen (høres skummelt ut!). Og hva sier de offisielle kanalene? På utdanning.no skriver UMB følgende: “Hvorfor studere Geomatikk? Et opplagt valg hvis du er interessert i kart, webapplikasjoner, navigasjon (GPS), 3D-spill eller lignende.” 3d-spill, det er kanskje ikke der hodemangelen er størst?

Spør du en hvilkensomhelst ikke-geomatiker om hva geomatikk er jeg tror du får et lite opplysende svar. Kanskje “noe med kart”, hvis du er heldig, eller “GPS og sånn”, som mange i min omgangskrets sier. Eller “fancy geolog”, eller “matematiker som bruker kvarts istedenfor penn og papir”? Vi kan le litt av at folk ikke helt skjønner hva vi driver med, men vi har nå i det minste klart å samle oss bak et felles navn. Men jeg tror også at det innad blant oss er stor spredning i hva vi legger i begrepet. Og det er ikke så rart, vi driver jo med så forskjellige ting. Dette kan til tider være en utfordring. Det å sende inn foredrag til Geomatikkdagene kan være en spennende øvelse: kan jeg vise kode på slidene mine? Kan jeg anta at publikum vet hva HTML er?

På den annen side: denne miksen av fagretninger(?) innenfor faget(?) gjør at det alltid er spennende å møte folk som jobber med det. Du kan nesten alltid forvente å lære noe nytt, vi har en felles referanseramme i bunn (tok du den?) og det er faktisk litt gøy å fortelle folk at du er geomatiker. Når du har ytret dette kan to reaksjoner oppstå: 1. Pinlig stillhet etterfulgt av snakk om været, eller 2. En lengre diskusjon om hvorfor hytta til naboen ikke finnes “på GPSen”. Vokt deg bare vel for å si “Jeg driver med Geomatikk, men det vet sikkert ikke du hva er”. En oppvakt frisør gav meg følgende tilsvar på det utsagnet: “Nei, jeg er jo bare en dum frisør, jeg”.

Ninjatriks i Javascript, del 1

Jeg drister meg frempå med en “del 1″, selv om jeg ikke vet om det blir noen del 2, 3 etc..

Uansett: Jeg skriver jo endel Javascript, og jeg ser endel javascript-kode rundt om kring. En ting som irriterer meg er hvordan folk roter til det globale namespacet, og dermed tenkte jeg å dele noen triks for å holde styr på namespaces etc i Javascript.

Detter er på ingen måte noen fasit, men det er noe som jeg synes fungerer godt selv. Har du inspill eller korreksjoner lærer jeg gjerne av deg!

Hold det globale namespacet ryddig!

Alle funksjoner og variabler du definerer i Javascript legger seg i det “globale namespacet”. Dvs, du kan få trøbbel med at du overskriver variabler eller funksjoner som finnes fra før (hvis disse ikke har vært ryddige). Men, frykt ikke, løsningen er rimelig enkel: namespacing! Hvordan? Vel, Javascript har ikke noe namespace-konsept, men det har objekter (eller, object literals, dvs {}). Disse kan vi bruke som namespace. Si at jeg vil ha et namespace Atlefren. Da kan jeg lage det som følger:


var Atlefren = {};

Da kan jeg, lage funksjonene mine som dette:


Atlefren.myFunc = function () {
    return "foo";
};

Problemet med denne løsningen er ser du hvis du i fil a.js skriver følgende:


var Atlefren = {};
Atlefren.myFunc = function () {
    return "foo";
};

og i fil b.js:


var Atlefren = {};
Atlefren.myOtherFunc = function () {
    return "bar";
};

Hvis du inkluderer a.js og så b.js vil myFunc være “undefined”, fordi “namespacet” Atlefren settes til et tomt objekt i toppen av b.js. Et triks for å omgå dette er følgende:


var Atlefren = window.Atlefren || {};

Her skjer følgende: “namespacet” Atlefren settes lik namespacet Atlefren fra “window” (som er det globale namespacet), og hvis ikke dette finnes lages det et nytt, tomt objekt.

Dermed vil både Atlefren.myFunc og Atlefren.myOtherFunc eksistere etter at a.js og b.js er lastet, og rekkefølgen du laster dem i har heller ikke noe å si.

Selveksekverende funksjoner
Men, vi er ikke helt i mål. Hva med diverse småfunksjoner du ikke vil eksponere ut? ta dette eksempelet:


var Atlefren = window.Atlefren || {};

function someHelpingFunction(string) {
    return string + "!";
}

Atlefren.myFunc = function () {
    return someHelpingFunction("foo");
};

Nå vil Atlefren.myFunc være pent og pyntelig inne i namespacet, mens someHelpingFunction vil ligge i det globale namespacet. Vi kunne såklart lagt someHelpingFunction i Atlefren-namespacet også, men det blir upent. For det første vil det da bli masse, unødvendige funksjoner i Atlefren-namespacet, for det andre må du bruke notasjonen


namespace.funksjonsnavn = function () {};

hver gang du skal lage en ny funksjon. Det er mye skriving. Heldigvis finnes det en løsning, og den inkluderer anonyme funksjoner. Såkalte selv-eksekverende funksjoner. Teorien er sm følger:

Du kan definere en anonym funksjon som følger:


function () {};

Vi vet også at denne kan assignes til en variabel og kjøres:


var func = function () {};
func();

Dette kan også gjøres i en go:


(function () {/*do someting*/}());

Her lager vi en funksjon, og kjører den umiddelbart (det siste () er kallet til funksjonen). Det er “god skikk” å legge et ekstra par parenteser rundt en slik funksjon, for å signalisere at dette er en “selveksekverende funksjon) Denne funksjonen blir kjørt en gang og så har du ikke tilgang til den mer. Det fine her er at funksjoner at et eget scope, variabler og funksjoner definert inne i en funkjsjon legges IKKE i det globale namespacet. Dermed kan vi gjøre følgende:


var Atlefren = window.Atlefren || {}; //definer namespacet
(function () {
    //denne funksjonen finnes kun i scopet til den selv-eksekverende funksjonen
    function someHelpingFunction(string) {
        return string + "!";
    }

    // denne legges på Atlefren-namespacet som før
    Atlefren.myFunc = function () {
        return someHelpingFunction("foo");
    };
}());

Ett lite problem gjenstår: jeg må fortsatt skrive hele namespacet mitt for hver funksjon jeg skal eksponere. Dette kan bli slitsomt hvis jeg har et langt, nøstet namespace (eks org.atlefren.demo.stuff, for Java-fanatikerene), eller om jeg skal endre navnet på namespacet mitt. Heldigvis er jo den selveksekverende funksjonen nettopp en funksjon, og kan dermed ta argumenter. Vi kan dermed sende inn namespacet som et argument og bruke dette (jeg har lagt meg på å kalle parameteret ns, så jeg alltid vet hva jeg jobber med:


var Atlefren = window.Atlefren || {}; //definer namespacet
(function (ns) {
    "use strict";

    //denne funksjonen finnes kun i scopet til den selv-eksekverende funksjonen
    function someHelpingFunction(string) {
        return string + "!";
    }

    // denne legges på Atlefren-namespacet som før
    ns.myFunc = function () {
        return someHelpingFunction("foo");
    };
}(Atlefren));

Sånn, nå har vi et ryddig public namespace, ikke så mye clutter og fint strukturert kode. Hvis du er eksta nøye kan du legge på en “use strict” øverst i den selv-eksekverende funksjonen, for å fortelle javascript-parseren at du skriver “skikkelig” javascript (som jeg har gjort).