Grunderna i JavaScript-programmering
Om du kan något annat programmeringsspråk i C-familjen (t.ex. C, C++, C# eller Java) kan du redan mycket av grunderna i JavaScript, då väldigt mycket påminner om dessa andra språk. Dock finns det en del skillnader, såsom hur man deklarerar variabler och dylikt. Det bör dock inte vara alltför svårt att sätta sig in i skillnaderna.
Här kommer vi att gå igenom programmering från scratch, så om du har lite kunskaper inom området kanske du vill snabbskumma igenom de första aktiviteterna i denna sektion...
Vad är programmering?
Programmering är en typ av problemlösning där man tar fram en ”steg för steg”-beskrivning för hur datorn ska lösa ett problem eller en klass av problem. Datorerna är egentligen rätt dumma och kan enbart utföra väldigt grundläggande uppgifter, typ den enklaste matematik. Däremot är datorer extremt snabba (och relativt tillförlitliga). På grund av denna snabbhet kan man skapa problemlösningar som i grund och botten är uppbyggda av tonvis av små, enkla operationer, som stegvis utför mer allt mer komplexa uppgifter. Oavsett i vilket programmeringsspråk vi programmerar, så kommer vår kod att översättas till något som datorn kan fatta och utföra. I slutändan är det alltid maskinkod, dvs processorns egna språk, som utför arbetet. Varje kodrad som återfinns i ett program kan resultera i en mängd operationer som måste genomföras för att uträtta det koden beskriver. Till och med när man kör de enklaste programmen, så utför datorn myriader av operationer.
Datorn har ett väldigt litet antal operationer som den kan utföra. Varje programmeringsspråk har en uppsättning ord och regler som avgör vad språket "fattar" och kan utföra. Det är sällan mer än ca 100 grundfunktioner som finns i ett programmeringsspråk. När vi ska lösa våra problem måste vi formulera lösningar som bara använder sig av dessa ord. 100 ord är inte så mycket, det är färre ord än en hund eller en tvååring kan förstå. Men liksom när man försöker kommunicera med en hund eller en tvååring så kan det vara svårt att förklara ett komplext problem med ett starkt begränsat vokabulär. Datorn har dock en fördel i jämförelse med hundar och små barn, den utför exakt vad du beodrar den att göra. Den gör vare sig mer eller mindre än det du säger åt den att göra (hur dumma och felaktiga dina order än må vara).
När man programmerar går man igenom flera faser. Man börjar med att analysera det problem man vill lösa. Man försöker, om möjligt, att reducera problemet till flera, mindre komplexa delproblem. Därefter hittar man på lösningsförslag till varje delproblem och försöker sedan att kombinera samman dellösningarna till en komplett lösning som genomför allt man förväntade sig.
Programmeringe påminner lite om hur man löser vissa problem i matematiken, t.ex. såna där problem där "Lisa har tre äpplen, Per har två skohorn...". Man vet vad man har för startvillkor och man vet var man vill hamna – det svåra är att hitta vägen ifrån A till B. Ibland måste man ta en liten avkrok på vägen och klara av några delproblem som förhoppningsvis kan ge ledning till hur man ska komma fram till slutlösningen. Även det som låter väldigt enkelt kan bli krångligt och komplext när man ska uttrycka det som kod. Gillar du att lösa problem är programmering den ultimata utmaningen!
I tidiga faserna av programmering jobbar man ofta på papper. Man kanske ritar upp problemet, t.ex. med flödesdiagram. Ett annat sätt för att beskriva lösningsförslag är att använda sig av så kallad pseudokod. Pseudokod är ett mer formaliserat sätt att sätta ord på programmeringslösningar. Det är en blandning av vanligt, mänskligt språk och programmeringsspråk. Det finns ingen standard för hur pseudokod ska se ut. Man skriver mer eller mindre i klartext hur lösningen ska fungera, steg för steg.
Algoritm
Problemlösningar av typen steg-för-steg, kallas för algoritm. Algoritmer känner du säkert igen ifrån matematiken. Den vanliga metoden för att lösa en andragradsekvation, PQ-formeln, är ett exempel på en algoritm. När man använder den formeln jobbar man steg för steg för att på ett generellt sätt lösa en andragradsekvation. Andra vardagsexempel på algoritmer kan vara matrecept, bygginstruktioner (typ såna man får med IKEA-möbler) eller liknande.
Det är viktigt att man utför de olika stegen i en algoritm i korrekt ordning, annars kommer resultatet inte att bli korrekt. Vanligtvis utför man stegen i en algoritm ett efter ett. Man börjar i toppen och går framåt rad för rad. Detta kallas att arbeta sekventiellt eller synkront. De flesta enkla datorprogram fungerar på detta sätt. Ibland kan man ha en instruktion som säger att man ska hoppa över en rad om något speciellt villkor är uppfyllt. Detta kallar man ibland för selektion, dvs man väljer ut vilka rader som ska köras. Det är också vanligt förekommande att man uppmanas att upprepa en, eller flera, rader i en algoritm, kanske upprepar man tills något villkor är uppfyllt. Detta kallas för iteration, eller upprepning. Vi behöver iofs en sak till för att kunna programmera. För att kunna beräkna saker måste vi även ha lagring. Vi måste på något vis kunna spara undan våra beräkningar. Alla dessa begrepp sammantagna är grunden till programmering; lagring, sekvens, selektion och iteration. Har vi tillgång till dessa saker kan vi lösa allt! (I alla fall allt som går att lösas...)
Programmering är oftast en iterativ process, där man jobbar med stegvis förfining. Vilket är ett halvkrångligt sätt att säga att man gör om saker om och om igen, men man försöker förbättra resultatet varje gång. Ett exempel på det kan vara att man i första skedet skapar en algoritm som gör det den ska, utan att bry sig om hur fort algoritmen utför sitt arbete. I nästa iteration, eller upprepning, försöker man kanske förbättra algoritmen så att den går snabbare. På så vis förbättrar man sitt program stegvis.
Exempel: Är något ett primtal?
Låt säga att vi ska kontrollera om ett tal är ett primtal. När man ska lösa det problemet, så kanske man går igenom en process som påminner om följande:
- Först måste vi ta reda på vad ett primtal är…
Så här säger Wikipedia; Ett primtal är ett heltal p, som är större än 1 och som bara är jämt delbart med ±1 och ±p…
- Om man funderar lite kommer man fram till att man ”bara” behöver prova om talet är delbart med allt som är mindre än talet själv. Ettan ska vi skippa, då den inte räknas enligt definitionen.
- Vi uttrycker det med lite pseudokod:
Sätt nämnare = 2 Medan nämnare är mindre än tal Om tal / nämnare = jämt Tal är ej primtal Annars Öka nämnare med 1
function primtal(tal) {
var nämnare = 2;
while( nämnare < tal ) {
if( tal % nämnare == 0 ) {
return false;
}
}
return true;
}
En relativt ineffektiv lösning (och lite buggig)… Även om vi inte kan programmering så bra ännu, så går det faktiskt att läsa vad som händer i koden ovan. Om vi bortser ifrån sådant vi inte fattar, som t.ex. var
, ser vi att koden är rätt så lik vår pseudokod, med den stora skillnaden att sakerna står på halvengelska.
Funktioner
Vad vi har skapat är en ny funktion, ungefär som man gör i matematiken när man skapar funktioner av typen f(x). Funktioner är ett sätt på vilket man kan skapa små dellösningar. Man skriver små kodsnuttar som man sedan kan kombinera till större lösningar. Man skulle kunna säga att man utvidgar programmeringsspråket med just de specifika finesser som man själv behöver. I många fall går funktionerna även att återanvända när man skriver andra program. Som programmerare jobbar man ständigt på att utvidga sin verktygslåda av lösningar, algoritmer och funktioner.
Kärt barn har många namn; det är också vanligt att kalla funktioner för metoder, rutiner eller subrutiner. Även om det skiljer lite mellan den korrekta definitionen på hur man ska använda de olika namnen, så kan man säga att alla är godtagbara och oavsett vilket namn du använder bör programmeringskunniga fatta vad du menar. Som vi kommer att se så är det rätt vanligt inom programmering att saker har flera olika namn.
Satser
Varje komplett rad i ett JavaScript-program kallas för en sats (ibland delar man upp en sats på flera rader). Uttrycket kommer ifrån matematikens och logikens värld. Ett exempel på en sats i vår primtals-funktion är;
var nämnare = 2;
I den satsen skapar vi en variabel och vi ger den namnet nämnare samt att vi tilldelar den värdet 2. Varje sats genomför oftast någon "enkel" deluppgift/delsteg i vår algoritm. Man kan självklart kalla detta för mycket annat än sats, t.ex. kodrad, programrad, uttryck, osv.
För att indikera var en sats avslutas skriver man ett ";
"-tecken. Så gott som alla programrader ska avslutas på detta vis. Det finns ett fåtal undantag där man inte ska avsluta en programrad med ”;
”. Vi återkommer till dessa längre fram...
Det är ett vanligt fel att man glömmer ";
"-tecknet och då kommer kanske programmet inte att kunna köras korrekt. Vanligtvis är avsaknaden av ";
" en av de första saker du ska kontrollera då ditt program inte vill köra. Här är dock JavaScript mindre känsligt än andra språk i C-familjen. Faktum är att man i många fall kan utelämna ";
"-tecknet. Det är dock inte att rekommendera, det skapar bara dåliga ovanor att göra detta.
Kodblock; { och }
Kodexemplet innehåller några tecken som du kanske inte är helt van vid att använda. Jag tänker främst på "{
" och "}
". Dessa kallas för klammerparenteser. De kan också heta klammer, måsvingar, braces, curly braces, osv. De senare är de engelska namnen på tecknen. Vi programmerare kör ofta med engelska eller snarare svengelska uttryck, vilket är rätt naturligt då de flesta programmeringsspråk är baserade på engelska. Engelskan är förstås programmeringens "modersmål", då språken baseras på engelska ord och så gott som all dokumentation kommer först och främst (och kanske enbart) på engelska.
Vad man än kallar klamrarna, så har de en mycket speciell betydelse i JavaScript (och många andra programmeringsspråk). De används för att definiera ett kodblock. Det vill säga man har ett antal sats-rader som ska hänga samman som en enda stor sats och som ska utföras tillsammans (de körs dock inte samtidigt, utan de utförs fortfarande sekventiellt). Det kan vara kod som enbart ska köras när något speciellt villkor är sant (en så kallad if
-sats) eller kod som ska upprepas flera gånger (en så kallad slinga eller loop). Lägg märke till att block inte avslutas med ett ";
"-tecken.
I vår kodsnutt har vi exempel på något av det mest grundläggande som behövs för programmering, nämligen variabler. Dessa används för att lagra värden. Speciellt viktigt är att vi kan lagra undan resultat och delresultat ifrån våra beräkningar. Vi återkommer till variabler alldeles strax.
I koden har vi även exempel på några av de mest centrala begreppen i programmering; upprepning och val. Eller för att använda fackspråk; iteration och selektion. Upprepning gör att vi kan köra en bit av vår programkod flera gånger. Medan val möjliggör att vi kan styra programflödet och köra olika kodbitar beroende på diverse villkor. De flesta programmeringsproblem går att reducera till lagring, upprepning och val. Faktum är att matematikern Alan Turing bevisade att just dessa grundkoncept är vad som krävs för att kunna beräkna allt som är beräkningsbart.