Översikt
Andra kursveckan och nu ska du börja skriva kod och fortsätta gå igenom fler grundläggande begrepp. Information om veckans upplägg annonseras löpande i kursens Zulip-kanal.
Stödjande inspelningar
Section titled “Stödjande inspelningar”Kurslitteraturen är en av de delar som driver kursen framåt, men det kan vara svårt att själv strukturera upp innehållet. Vad är relevant? Vad ska jag fokusera på i kursen? De stödjande inspelningarna är gjorda för att ge detta sammanhang. Det är av yttersta vikt att du tar del av dessa!
Variabler och konstanter
Section titled “Variabler och konstanter”Variabler och konstanter är några av de absolut viktigaste byggstenarna i programmering. Hur skapar du dessa och vad ska du tänka på när det kommer till namngivning?
Varför variabler?
Section titled “Varför variabler?”Hittills har vi skrivit lösa uttryck – 12 + 13 ger 25, men vi kan inte jobba vidare med det värdet. Variabler löser det: de låter programmet komma ihåg värden genom att binda ett namn till ett värde. Vi säger att vi tilldelar variabeln ett värde.
En variabel deklareras med nyckelordet let följt av ett namn. Sedan ES6 (2015) är let standarden – tidigare användes var, som fortfarande förekommer i äldre kod och har väsentliga skillnader mot let (bl.a. i hur scope och hoisting fungerar).
let count // undefined – inget värde tilldelat ännulet result = (4 + 8) * 3 + 8 // 44Om ingen initiering görs får variabeln automatiskt värdet undefined. När ett värde väl är tilldelat kan det ändras, och variabeln kan användas i nya uttryck:
let count = 4 * 12 // 48count = count + 12 // 60JavaScript är löst typat, vilket betyder att en variabel kan tilldelas ett värde av en annan typ än den ursprungliga. Det är möjligt men sällan en bra idé – välj istället separata variabler med tydliga namn.
Namngivning
Section titled “Namngivning”Bra variabelnamn är centralt. Håll dig till engelska, välj beskrivande namn, och tillämpa camelCasing när namnet består av flera ord – varje ord utom det första inleds med versal:
let bestBookEver = 'The Hitchhiker\'s Guide to the Galaxy'let theMeaningOfLife = 42Tillåtna tecken är a–z, A–Z, 0–9, _ och $. Första tecknet får inte vara en siffra. I praktiken håller man sig till a–z och A–Z. Namn får inte vara nyckelord eller reserverade ord (som let, const, class, return m.fl.) – annars uppstår syntaxfel.
Utöver camelCasing finns PascalCasing (versalt första bokstav i varje ord, används senare för klasser) och snake_casing (understreck mellan ord, vanligt i t.ex. Python). JavaScript-konventionen och kursens kodstandard kräver camelCasing.
Deklarera en variabel per rad – det underlättar läsbarhet och dokumentation.
Konstanter
Section titled “Konstanter”En konstant fungerar som en variabel med två skillnader: den måste ges ett värde när den deklareras, och värdet kan sedan inte ändras. Försök att ändra det kastar ett TypeError.
const firstName = 'Johan'firstName = 'Mats' // TypeError: Assignment to constant variable.Däremot går det bra att använda värdet för att skapa nya värden:
const firstName = 'Johan'const fullName = firstName + ' Doe' // Skapar en ny sträng – ändrar inte firstNameDet här fungerar eftersom strängar är immutabla – man kan inte ändra en befintlig sträng, bara skapa nya utifrån den.
Namngivning av konstanter diskuteras i kurslitteraturen: vissa föredrar MY_FAVORITE_NUMBER (versaler med understreck) för värden som är hårdkodade och aldrig förändras, medan camelCasing används för konstanter som tilldelas dynamiskt vid körning. I kursen används camelCasing genomgående för enkelhetens skull.
Räckvidd (scope)
Section titled “Räckvidd (scope)”En variabels scope är det kodblock där den kan användas. Variabler och konstanter deklarerade med let och const har block scope – de existerar bara inom de klammerparenteser där de skapades.
{ let bestBookEver = 'The Hitchhiker\'s Guide to the Galaxy' console.log(bestBookEver) // Fungerar}console.log(bestBookEver) // ReferenceError: bestBookEver is not definedDet är möjligt att ha variabler med samma namn i ett yttre och ett inre block – de är då två separata variabler. Inom ett och samma block däremot kan ett namn bara deklareras en gång.
Observera att klammerparenteser i JavaScript har dubbel betydelse: de skapar block, men används också för objektliteraler ({ name: 'Johan' }). Sammanhanget avgör tolkningen, och det lär man sig snabbt.
Funktioner
Section titled “Funktioner”För att kunna dela upp din kod i mindre, logiska stycken så behöver du använda funktioner. Men hur fungerar detta?
Inbyggda funktioner
Section titled “Inbyggda funktioner”När ett JavaScript-program startar finns ett stort antal inbyggda funktioner tillgängliga direkt. console.log är ett välbekant exempel – den skriver ut ett värde i konsolfönstret. Math.min returnerar det minsta av flera inmatade värden, och Math.random ger tillbaka ett slumpmässigt tal från och med 0 upp till (men inte inklusive) 1. Andra användbara matematikfunktioner är Math.max, Math.floor och Math.ceil.
Varför funktioner?
Section titled “Varför funktioner?”Det finns inte inbyggda funktioner för allt – förr eller senare måste man skriva sina egna. Att dela upp ett program i funktioner är centralt av flera skäl: det strukturerar koden, skapar överblick, och undviker att identisk kod upprepas på flera ställen. Det sistnämnda brukar sammanfattas som principen DRY – Don’t Repeat Yourself – ett begrepp som återkommer genom hela kursen. Funktioner gör dessutom koden enklare att testa.
En bra liknelse är matlagning: “laga mat” är en övergripande funktion som i sin tur innehåller delfunktioner som “koka potatis”, “steka kött” och “göra sås”. På samma sätt bryts ett program ner i lagom stora, namngivna delar.
Anropa en funktion
Section titled “Anropa en funktion”En funktion anropas genom att skriva dess namn följt av parenteser. Inuti parenteserna skickas eventuella argument – de värden som funktionen ska arbeta med:
console.log('Hello, World!') // Skickar en sträng som argumentconsole.log() // Anrop utan argument – skriver ut en tom radlet randomNumber = Math.random() // Returvärdet sparas i en variabelParenteserna är obligatoriska – utan dem sker inget anrop. Varje funktion returnerar alltid ett värde. Saknas en explicit return-sats returneras undefined.
Tre sätt att skapa funktioner
Section titled “Tre sätt att skapa funktioner”Funktionsdeklaration
Section titled “Funktionsdeklaration”Det klassiska sättet: nyckelordet function, följt av ett namn, en parameterlista inom parenteser och en kropp inom klammerparenteser.
function sayHelloTo(name) { let greeting = 'Hello, ' + name + '!' return greeting}
let whatIsSaid = sayHelloTo('Ellen Nu')console.log(whatIsSaid) // OUTPUT: Hello, Ellen Nu!Funktioner skapade med funktionsdeklaration hoistas – JavaScript lyfter dem till toppen av programmet innan koden körs, vilket innebär att de kan anropas även innan de är skrivna i filen.
Funktionsuttryck
Section titled “Funktionsuttryck”Här tilldelas en funktion till en variabel eller konstant. Funktionen behöver inget eget namn.
const anotherSayHelloTo = function (name) { let greeting = 'Hello, ' + name + '!' return greeting}
let whatIsSaid = anotherSayHelloTo('Ellen Nu')console.log(whatIsSaid) // OUTPUT: Hello, Ellen Nu!Använd const för funktionsuttryck – det förhindrar att referensen råkar skrivas över. Till skillnad från funktionsdeklarationer hoistas inte funktionsuttryck, och de kan inte anropas innan de initierats.
Arrow function-syntax
Section titled “Arrow function-syntax”Sedan ES6 (2015) finns ett kortare skrivsätt med en pil (=>):
const yetAnotherSayHelloTo = (name) => { let greeting = 'Hello, ' + name + '!' return greeting}Innehåller kroppen bara en sats kan klammerparenteser och return utelämnas:
const yetAnotherSayHelloTo = (name) => 'Hello, ' + name + '!'Saknar funktionen parametrar måste tomma parenteser ändå anges:
const getTheMeaningOfLife = () => 42Alla tre sätten beter sig likadant när det gäller argument, parametrar och returvärden.
Räckvidd (scope)
Section titled “Räckvidd (scope)”Variabler och parametrar som deklareras inuti en funktion är lokala – de existerar bara inom funktionens kropp och är inte åtkomliga utifrån:
function getFullName(firstName, lastName) { let fullName = firstName + ' ' + lastName // Lokal variabel return fullName}
console.log(fullName) // ReferenceError – fullName finns inte härParametrarna firstName och lastName räknas också som lokala variabler i funktionen.
Parametrar och standardvärden
Section titled “Parametrar och standardvärden”En parameter kan ges ett standardvärde som används om inget argument skickas med vid anropet:
function getFullName(firstName, lastName = 'Doe') { let fullName = firstName + ' ' + lastName return fullName}
getFullName('Ellen', 'Nu') // → 'Ellen Nu'getFullName('Nisse') // → 'Nisse Doe' (standardvärdet används)getFullName() // → 'undefined Doe'Standardvärden på parametrar signalerar till andra utvecklare vilka argument som är obligatoriska och vilka som är valfria. Parametrar utan standardvärde förväntas alltid skickas med.
Moduler
Section titled “Moduler”Jättebra att du kan dela upp din kod i funktioner, men hur gör du om du vill dela upp din kod i flera filer?
Varför moduler?
Section titled “Varför moduler?”När ett program växer och all kod ligger i en enda fil ökar risken för att koden tappar struktur och blir svår att förändra. Genom att dela upp programmets kod i flera filer – moduler – undviks det problemet. En modul är ett litet delprogram som kan ange vilka andra moduler den beror av, och framför allt vilken funktionalitet den erbjuder andra moduler att använda.
ECMAScript-moduler
Section titled “ECMAScript-moduler”Sedan ECMAScript 6 (2015) har JavaScript inbyggt stöd för moduler – ECMAScript-moduler (ES-moduler, ESM). En modul exporterar värden med export:
function bye () { console.log('God bye!') // exporteras inte – bara tillgänglig i modulen}
export function hello () { console.log('Hello, World!') // namngiven export ("named export")}En annan modul laddar den med import:
import * as myGreeting from './my-greeting.js' // namnrymdsimport – importerar allt exporteratimport { hello } from './my-greeting.js' // namngiven import – importerar bara helloBara det som faktiskt exporterats kan anropas utifrån:
myGreeting.hello() // OUTPUT: Hello, World!myGreeting.bye() // ERROR: TypeError: myGreeting.bye is not a functionCommonJS – ett äldre sätt
Section titled “CommonJS – ett äldre sätt”Innan ESM var CommonJS ett av de populära modulsystemen, och används fortfarande mycket inom Node.js eftersom ESM-stödet där länge var experimentellt:
function hello () { console.log('Hello, World!')}
module.exports.hello = hello
// app.jsconst myGreeting = require('./my-greeting.js')myGreeting.hello()Det här sättet räknas idag som utdaterat till förmån för ESM.
Aktivera ECMAScript-moduler i Node.js
Section titled “Aktivera ECMAScript-moduler i Node.js”Node behandlar JavaScript-kod som CommonJS-moduler som standard. För att istället använda ES-moduler läggs fältet type med värdet "module" till i package.json – enklast skapad med npm init -y och sedan kompletterad:
{ "name": "my-awesome-app", "type": "module", "main": "app.js"}Saknas den inställningen ger Node ett tydligt felmeddelande vid körning som talar om att ESM-syntax använts utan att den aktiverats.
npm – en samling paketerad kod
Section titled “npm – en samling paketerad kod”npm-registret innehåller paket, och ett paket kan i sin tur innehålla flera moduler. Vilka paket en applikation använder beskrivs i package.json, under dependencies och devDependencies (tillsammans med vilken version av respektive paket). Paket installeras med npm install PAKETETS_NAMN och hamnar i katalogen node_modules. Saknas den katalogen (till exempel efter en färsk git clone) installeras alla beroenden i ett svep med npm install utan argument.
Läsanvisningar
Section titled “Läsanvisningar”Under läsanvisningar hittar du veckans kapitel som ska läsas i kurslitteraturen. Planera upp och dela upp läsningen under veckan.
Guider
Section titled “Guider”Under veckan behöver du komma igång med utvecklingsmiljön Visual Studio Code och versionshanteringsverktyget Git. Detta för att kunna genomföra de första övningsuppgifterna. Följ guiderna för detta och ta hjälp på handledningarna eller i kursens Zulip-kanal om du kör fast!
Handledning
Section titled “Handledning”Kört fast? Strular Git? Problem med en övningsuppgift? Då ska du definitivt vara med på handledningen där du har möjlighet att fråga kursledning och amanuenser om vad som helst.
Campus har denna aktivitet i schemalagd sal och distans träffas i zoom och har därefter individuell handledning i Zulip.
Glöm inte att ställa frågor (i god tid) inför handledningen i formuläret:
Utmaningar
Section titled “Utmaningar”Även denna vecka finns ett antal utmaningar att lösa för att hjälpa dig i din lärprocess. Lägg lite tid på att läsa igenom dem. Det är inte omöjligt att det dyker upp några nya utmaningar på veckans fredagshäng.
Studiefrågor
Section titled “Studiefrågor”Här är ett antal frågor som du kan försöka besvara och diskutera tillsammans med en AI-assistent. Tveka inte att lyfta någon av frågorna till handledningen för att fortsätta diskussionen med lärare och studiekamrater.
- Berätta kort om utvecklingsverktyget vscode.
- Berätta kort om historiken bakom vscode.
- Stämmer det att vscode är byggt med teknikerna HTML, CSS och JavaScript?
- Berätta kort om Git.
- Berätta kort om GitLab.
- Berätta kort om variabler och konstanter i JavaScript.
- Berätta kort om funktioner i JavaScript.
- Berätta kort om ESM moduler i JavaScript.
- Hur kan ett program “Hello World” se ut om jag bygger det med variabler, funktioner och moduler i JavaScript och sedan kör det i Node?
Här är en utskrift från hur det kan se ut när frågorna ovan diskuterats med en AI-assistent.
Här följer tips till hur du kan prioritera bland kursmaterialet för att komma igång med veckan.
- Börja med att installera vscode och bekanta dig med texteditorn/utvecklingsverktyget.
- Jobba igenom guiden med Git & GitLab och bekanta dig med de båda verktygen.
- Gör den första övningsuppgiften för att bekanta dig med hur man klonar ett repo och exekverar koden. Se även om du kan tjuvkika på lösningen.
Ett standardtips är alltid att titta igenom de inspelade föreläsningarna och läsanvisningarna.
