Gå til indhold
Jan Engelbrecht Pederseb Logo

Moderne JavaScript (ES6+ & Full-Stack Fundament)

Et komplet kursus fra fundamentale byggeklodser til asynkron programmering, DOM-manipulation og moderne arkitektur.

Moderne JavaScript (ES6+ & Full-Stack Fundament)

Et komplet kursus fra fundamentale byggeklodser til asynkron programmering, DOM-manipulation og moderne arkitektur.

Del 1: Introduktion og dit første script (Niveau: Begynder)

Del 2: Fundamentale byggeklodser

Del 3: Datastrukturer og funktioner

Del 4: DOM-manipulation og events (Niveau: Øvet)

Del 5: Asynkron JavaScript og API'er

Del 6: Avanceret JavaScript og arkitektur (Niveau: Avanceret)

Del 7: Værktøjskassen og næste skridt

Del 1: Introduktion og dit første script

Dette modul klæder dig på til at forstå, hvad JavaScript er, hvordan det samarbejder med HTML og CSS, og hvordan du skriver dit allerførste script.

Lektion 1: Hvad er JavaScript?

JavaScripts rolle på webben
Når man bygger en hjemmeside, arbejder tre kerneteknologier sammen. Du kan tænke på det som et hus:

Teknologi Metafor Rolle på webben
HTML Husets rå skelet og mure. Struktur: Definerer tekster, knapper og billeder.
CSS Maling, tapet og møbler. Design: Styrer farver, layouts, skrifttyper og udseende.
JavaScript Strøm, kontakter og automatiske døre. Opførsel: Gør siden interaktiv og levende.

Uden JavaScript ville hjemmesider være statiske dokumenter. JavaScript gør det muligt at lave pop-up-vinduer, opdatere indhold uden at genindlæse siden, lave animationer og reagere på brugerens klik.

Klientside vs. Serverside

  • Klientside (Browseren): Traditionelt kører JavaScript direkte i brugerens browser (Chrome, Safari, Edge). Det betyder, at det er brugerens egen computer, der udfører koden.
  • Serverside (Node.js): I dag kan JavaScript også køre på en webserver takket være et værktøj, der hedder Node.js. Det betyder, at du kan bruge JavaScript til at snakke med databaser og bygge hele backend-systemer. I dette kursus starter vi i browseren.

Lektion 2: Opsætning og værktøjer

Du behøver ikke installere tunge programmer for at programmere i JavaScript. Faktisk har du allerede alt, hvad du skal bruge, installeret på din computer.

1. Browserens udviklerværktøjer (Console)
Alle moderne browsere har en indbygget "konsol", hvor du kan skrive og teste JavaScript-kode med det samme.

  • Åbn din browser (f.eks. Google Chrome).
  • Højreklik et tilfældigt sted på en webside og vælg Undersøg (eller tryk på F12 / Cmd + Option + J på Mac).
  • Klik på fanen Console i menuen, der dukker op. Dette er din JavaScript-legeplads.

2. Kodeeditor (VS Code)
Til rigtige projekter skal du bruge en kodeeditor. Download og installer den gratis Visual Studio Code (VS Code), hvis du ikke allerede har den.

Dit første script og indlæsning

Lektion 3: Dit første script

Nu skal vi skrive dit allerførste JavaScript-kode. Det gør vi ved at oprette en simpel HTML-fil og koble en JavaScript-fil på.

Trin 1: Opret filerne
Opret en ny mappe på din computer, kald den js-kursus, og åbn den i VS Code. Opret to filer:

  1. index.html
  2. script.js

Trin 2: Skriv HTML-koden
Indsæt følgende standard HTML-struktur i din index.html. Læg mærke til <script>-tagget i bunden, som henter vores JavaScript-fil:

<!DOCTYPE html>
<html lang="da">
<head>
    <meta charset="UTF-8">
    <title>Mit første JavaScript</title>
</head>
<body>

    <h1>Velkommen til mit JavaScript kursus</h1>
    <p>Åbn konsollen for at se magien.</p>

    <!-- Vi indlejrer vores JavaScript-fil her. 'defer' sikrer, at siden er læst før koden kører -->
    <script src="script.js" defer></script>
</body>
</html>
            

Trin 3: Skriv JavaScript-koden
Åbn din script.js fil og skriv følgende linje:

// Dette er en kommentar. JavaScript ignorerer denne linje.
console.log("Hello World! Min JavaScript-kode virker.");
            

console.log() er den vigtigste funktion i starten. Den bruges til at udskrive beskeder og teste værdier direkte i browserens konsol (Console).

Trin 4: Kør det
Dobbeltklik på din index.html-fil, så den åbner i din browser. Åbn browserens Console (som beskrevet i lektion 2). Du vil nu se teksten: Hello World! Min JavaScript-kode virker.

Lektion 4: Defer vs. Async (Hvordan JS indlæses)

Når en browser læser din HTML-fil, gør den det oppefra og ned. Hvis den støder på et tungt JavaScript-tag i midten, stopper den med at tegne websiden, indtil koden er hentet og kørt. Det kan gøre hjemmesiden langsom.
Derfor bruger vi attributter på vores <script>-tag for at styre indlæsningen:

  • Uden attributter (<script src="script.js">): HTML-indlæsningen pauses fuldstændig, mens scriptet hentes og køres. (Bør undgås i head).
  • async (<script src="..." async>): Scriptet hentes i baggrunden, mens HTML indlæses. I det sekund scriptet er hentet, pauses HTML-indlæsningen, og scriptet køres med det samme. Godt til uafhængige tredjepartsscripts (f.eks. Google Analytics).
  • defer (<script src="..." defer>): Scriptet hentes i baggrunden, men browseren venter med at køre koden, til hele HTML-dokumentet er færdigbygget. Dette er standard best practice for dine egne scripts.

Del 2: Fundamentale byggeklodser

Dette modul lærer dig de mest grundlæggende byggesten i JavaScript, som er nødvendige for at skabe logik og struktur i din kode.

Lektion 5: Variabler og datatyper

Deklarering af variabler: let, const og var
En variabel er en container, der husker en værdi for os. I moderne JavaScript (ES6+) bruger vi to måder at oprette variabler på:

  • let: Bruges når variablens værdi skal kunne ændres (overskrives) senere i koden.
  • const (Konstant): Bruges når værdien aldrig skal ændres efter oprettelsen. Giver en fejl, hvis du prøver at overskrive den.
  • var: Det gamle nøgleord fra før 2015. Det har tekniske ulemper med hensyn til synlighed (scope) og bør helt undgås i moderne kode.
let alder = 25;
alder = 26; // Det er helt okay, værdien opdateres.

const fødselsår = 2000;
// fødselsår = 2001; // FEJL! Du kan ikke ændre en konstant.
            

Primitive datatyper
JavaScript finder selv ud af datatypen baseret på indholdet (dynamisk typet sprog). Her er de mest almindelige typer:

Datatype Forklaring Eksempel
StringTekst omgivet af anførselstegn eller backticks.const navn = "Mette";
NumberBåde heltal og decimaltal (bruger punktum).let pris = 99.95;
BooleanSandt eller falsk.let erLoggetInd = true;
NullEn bevidst tom værdi ("intet").let tomBeholder = null;
UndefinedEn variabel, der er oprettet, men ikke har fået en værdi endnu.let udefineretVariabel;

Tip om backticks: Hvis du bruger bagudvendte anførselstegn (`), kan du blande variabler direkte ind i din tekst (kaldet Template Literals):

console.log(`Hej, jeg hedder ${navn} og er ${alder} år gammel.`);
            

Lektion 6: Operatorer og logik

Sammenligningsoperatorer
Når vi sammenligner værdier, skal du være særligt opmærksom på JavaScripts særheder. Brug altid den stramme sammenligning (===).

let x = 5;      // Type: Number
let y = "5";    // Type: String

console.log(x == y);   // true  (== Tjekker KUN værdi, og tvinger typerne sammen)
console.log(x === y);  // false (=== Tjekker BÅDE værdi og datatype - Best Practice!)
console.log(x !== y);  // true  (Tjekker om de IKKE er helt ens)
            

Logiske operatorer (Logik)
Bruges til at kæde flere betingelser sammen.

  • && (OG): Begge sider skal være sande.
  • || (ELLER): Mindst én af siderne skal være sand.
  • ! (IKKE / Omvendt): Vender en boolean om (!true bliver til false).

Lektion 7: Kontrolstrukturer (Betingelser og loops)

Betingede sætninger (if, else, Ternary)
Betingelser bestemmer, hvilken kode der skal køres, afhængigt af om noget er sandt eller falsk.

let time = 14;

if (time < 12) {
    console.log("Godmorgen");
} else if (time < 18) {
    console.log("Goddag");
} else {
    console.log("Godaften");
}

// Ternary Operator (Kort if/else på én linje)
// format: betingelse ? hvis_sandt : hvis_falsk
let statusBesked = erLoggetInd ? "Velkommen tilbage!" : "Log venligst ind.";
            

Loops (Løkker)
Loops gentager en handling et bestemt antal gange.

// For-loop: Kører et præcist antal gange
// (Startværdi; Betingelse; Tæller-opdatering)
for (let i = 1; i <= 3; i++) {
    console.log(`Dette er gentagelse nummer ${i}`);
}

// While-loop: Kører så længe en betingelse er sand
let tæller = 0;
while (tæller < 3) {
    console.log(`Mens-løkke tæller: ${tæller}`);
    tæller++;
}
            

Del 3: Datastrukturer og funktioner

Dette modul lærer dig at skrive struktureret og effektiv kode, der kan håndtere store mængder data uden at gentage sig selv.

Lektion 8: Funktioner (Functions)

En funktion er en samling af kode, der udfører en specifik opgave. Du kan kalde funktionen igen og igen, hver gang opgaven skal løses.

Traditionelle funktioner vs. Arrow-funktioner
I moderne JavaScript (ES6+) bruger vi ofte den kortere Arrow-funktion syntaks (() => {}), især til mindre opgaver.

// 1. Traditionel funktionsdeklaration
function beregnMoms(beløb) {
    return beløb * 0.25;
}

// 2. Moderne Arrow-funktion (Pil-funktion)
const beregnMomsArrow = (beløb) => {
    return beløb * 0.25;
}

// Hvis en arrow-funktion kun gør én ting, kan vi fjerne {} og 'return' helt:
const kortMoms = beløb => beløb * 0.25;

console.log(beregnMoms(100));     // Udskriver: 25
console.log(kortMoms(200));       // Udskriver: 50
            

Forståelse af Scope (Synlighed)
Hvor du opretter dine variabler, bestemmer, hvor de kan læses fra.

  • Global Scope: Variabler oprettet uden for funktioner kan læses overalt i dit script.
  • Block/Function Scope: Variabler oprettet med let eller const inde i en funktion eller et loop eksisterer kun derinde.
let globalNavn = "Peter"; // Kan bruges overalt

const visNavn = () => {
    let lokalNavn = "Sofie"; // Eksisterer KUN inde i denne funktion
    console.log(globalNavn); // Virker fint
}

visNavn();
// console.log(lokalNavn); // FEJL! lokalNavn er ikke defineret uden for funktionen.
            

Lektion 9: Arrays (Lister)

Et array er en liste over elementer (f.eks. tekster, tal eller objekter) gemt i én enkelt variabel. Indeksering starter altid ved 0.

const biler = ["Volvo", "BMW", "Audi"];
console.log(biler[0]); // Udskriver: Volvo
            

Moderne Array-metoder (Iteratorer)
I stedet for at bruge traditionelle for-loops til at gennemgå en liste, bruger vi i moderne JavaScript indbyggede metoder, der gør koden langt mere læselig.

Metode Beskrivelse Eksempel
forEach()Gennemløber listen og udfører en handling for hvert element.biler.forEach(bil => console.log(bil));
map()Opretter et helt nyt array ved at ændre alle elementerne på listen.const storeBiler = biler.map(bil => bil.toUpperCase());
filter()Opretter et nyt array med de elementer, der opfylder en betingelse.const tal = [1, 5, 10, 15];
const højeTal = tal.filter(t => t > 8); // [10, 15]

Objekter og moderne ES6+ genveje

Lektion 10: Objekter (Objects)

Mens arrays er gode til lister, er objekter geniale til at beskrive en enkelt ting med flere forskellige egenskaber (Key-Value par).

Oprettelse og brug af objekter

// Oprettelse af et objekt
const bruger = {
    fornavn: "Mads",
    efternavn: "Nielsen",
    alder: 31,
    erAktiv: true,
    // En funktion inde i et objekt kaldes en metode
    siHej: function() {
        // 'this' refererer til det aktuelle objekt, vi er inde i
        console.log(`Hej, jeg hedder ${this.fornavn}!`);
    }
};

// Hent data ud af objektet (Dot-notation)
console.log(bruger.fornavn); // Udskriver: Mads
bruger.siHej();              // Udskriver: Hej, jeg hedder Mads!
            

Lektion 11: Destructuring og Spread Operator

Moderne JavaScript har smarte genveje til hurtigt at pakke data ud af objekter og arrays.

1. Destructuring (Udpakning)
Gør det muligt at trække værdier ud af et objekt og gemme dem i variabler på en enkelt linje.

// Traditionel måde:
// const fornavn = bruger.fornavn;
// const alder = bruger.alder;

// Moderne måde (Destructuring):
const { fornavn, alder } = bruger;
console.log(fornavn); // Udskriver: Mads
            

2. Spread Operator (...)
De tre prikker bruges til at kopiere eller sammensætte arrays og objekter lynhurtigt.

const primæreFarver = ["rød", "gul"];
const alleFarver = [...primæreFarver, "blå", "grøn"]; 
// Resultat: ["rød", "gul", "blå", "grøn"]

// Kopier et objekt og tilføj/ændr en egenskab samtidig:
const opdateretBruger = { ...bruger, alder: 32, by: "Odense" };
            

Del 4: DOM-manipulation og events

Dette modul forvandler dine statiske websider til interaktive oplevelser ved at kontrollere browserens visning i realtid.

Lektion 12: DOM (Document Object Model)

Når en browser indlæser en HTML-side, forvandler den koden til et interaktivt familietræ af objekter. Dette træ kaldes DOM-træet. JavaScript kan navigere rundt i dette træ for at finde, ændre, tilføje eller slette HTML-elementer.

1. Valg af HTML-elementer
Før du kan ændre noget på siden, skal du fortælle JavaScript, hvilket element du vil have fat i. I moderne JavaScript bruger vi primært metoden querySelector(), fordi den bruger præcis samme syntaks som CSS-selectors.

// Hent det første element med et bestemt ID (#)
const overskrift = document.querySelector("#hoved-overskrift");

// Hent det første element med en bestemt klasse (.)
const infoTekst = document.querySelector(".tekst-boks");

// Hent ALLE elementer med en bestemt klasse (returnerer en liste/NodeList)
const alleKnapper = document.querySelectorAll(".Gem-knap");
            

2. Ændring af indhold og tekst
Når du har fanget et element, kan du nemt ændre teksten eller den underliggende HTML-kode.

// Ændrer kun den rene tekst (Sikkert mod XSS)
overskrift.textContent = "Velkommen til min nye verden!";

// Ændrer indholdet og fortolker HTML-tags (Brug med omtanke)
infoTekst.innerHTML = "Dette er en <strong>vigtig</strong> besked!";
            

3. Manipulation af CSS og klasser
Du bør sjældent ændre CSS-styles direkte linje for linje i JavaScript (f.eks. element.style.color = "red"). Den professionelle måde er at definere klasserne i din CSS-fil, og derefter tænde og slukke for klasserne med JavaScript via classList.

const boks = document.querySelector(".min-boks");

boks.classList.add("aktiv");      // Tilføjer klassen .aktiv
boks.classList.remove("skjult");   // Fjerner klassen .skjult

// .toggle() tænder klassen, hvis den mangler, og slukker den, hvis den findes i forvejen (perfekt til mørkt tema / dark mode!)
boks.classList.toggle("dark-mode");
            

Lektion 13: Event håndtering (begivenheder)

JavaScript kan lytte efter "begivenheder" (events) på hjemmesiden. En begivenhed kan være, at brugeren klikker på en knap, scroller ned ad siden, sender en formular eller trykker på en tast på tastaturet.
For at lytte efter en begivenhed bruger vi funktionen addEventListener().

Grundlæggende klik-event

const knap = document.querySelector("#min-knap");

// Vi fortæller knappen, at den skal lytte efter et 'click'. 
// Når det sker, kører vi en arrow-funktion.
knap.addEventListener("click", () => {
    alert("Du klikkede på knappen!");
});
            

Formularhåndtering og event-objektet
Når en begivenhed udløses, sender JavaScript automatisk et event-objekt (ofte bare kaldet e eller event) med ind i funktionen. Dette objekt indeholder nyttig information om begivenheden.
Når du arbejder med formularer (<form>), genindlæser browseren automatisk siden som standard, når man trykker på "Send". Det vil vi typisk forhindre med JavaScript ved hjælp af e.preventDefault().

const formular = document.querySelector("#login-form");
const inputFelt = document.querySelector("#brugernavn");

formular.addEventListener("submit", (e) => {
    e.preventDefault(); // Stopper browseren i at genindlæse siden
    
    const indtastetNavn = inputFelt.value; // Henter teksten fra inputfeltet
    
    console.log(`Formularen blev sendt med navnet: ${indtastetNavn}`);
});
            

Event Delegation (Smartere lytning)
Hvis du har en liste med 100 elementer, er det meget tungt for computeren at sætte en addEventListener på hver eneste linje. I stedet sætter man én enkelt lytter på hele listen (forælderen) og bruger e.target til at finde ud af, nøjagtigt hvilket underelement brugeren klikkede på.

const liste = document.querySelector("#indkøbsliste");

liste.addEventListener("click", (e) => {
    // Tjek om det, brugeren klikkede på, rent faktisk er et listepunkt (<li>)
    if (e.target.tagName === "LI") {
        e.target.classList.toggle("streget-ud"); // Gør noget med det specifikke element
    }
});
            

Praktisk eksempel: Byg en interaktiv "tæller"
Lad os binde alt det lærte sammen i et lille, funktionelt eksempel. Forestil dig, at du har følgende HTML på din side:

<h1 id="tal-visning">0</h1>
<button id="plus-knap">Tæl op</button>
            

Her er JavaScript-koden, der vælger elementerne, holder styr på dataen (en variabel) og opdaterer DOM'en, hver gang der klikkes:

// 1. Vælg elementerne
const talVisning = document.querySelector("#tal-visning");
const plusKnap = document.querySelector("#plus-knap");

// 2. Definer vores data (State)
let tællerVærdi = 0;

// 3. Lyt efter klik og opdater siden
plusKnap.addEventListener("click", () => {
    tællerVærdi++; // Læg 1 til variablen
    talVisning.textContent = tællerVærdi; // Opdater teksten på skærmen
});
            

Del 5: Asynkron JavaScript og API'er

Dette modul lærer dig at forbinde dine applikationer med omverdenen ved at hente, sende og behandle data via eksterne tjenester.

Lektion 14: Asynkron programmering og event loop

Hvad betyder asynkron?
JavaScript er som udgangspunkt single-threaded og synkront. Det betyder, at browseren kører én linje kode ad gangen, oppefra og ned. Hvis en linje kode tager 5 sekunder at køre (f.eks. fordi vi venter på et svar fra en langsom server), ville hele din hjemmeside fryse fast i mellemtiden.
For at undgå dette bruger vi asynkron programmering. Det tillader JavaScript at starte en langvarig opgave i baggrunden, gå videre med at køre resten af koden, og derefter vende tilbage og gøre arbejdet færdigt, så snart baggrundsopgaven er klar.

Fra callbacks til promises
I gamle dage brugte man funktioner inde i funktioner (callbacks) til at håndtere asynkron kode. Det førte hurtigt til ulæselig kode kaldet "Callback Hell".
I dag bruger vi Promises (løfter). Et Promise er et objekt, der repræsenterer en asynkron operation, som kan befinde sig i tre tilstande:

  1. Pending (Afventer svar)
  2. Fulfilled (Succes – opgaven lykkedes, og vi fik data)
  3. Rejected (Fejlet – der skete en netværksfejl eller lignende)

Lektion 15: Fetch API og JSON

Når vi skal snakke med en anden server, bruger vi næsten altid formatet JSON (JavaScript Object Notation). Det er en tekststreng, der ligner et helt almindeligt JavaScript-objekt, og som er standarden for dataudveksling på internettet.

Hentning af data med fetch() (Den traditionelle Promise-metode)
Vi bruger den indbyggede funktion fetch() til at sende en anmodning til et API. fetch() returnerer et Promise, som vi kan håndtere med .then() og .catch().

// Vi henter en tilfældig bruger fra et gratis test-API
fetch("https://typicode.com")
    .then(response => {
        // Tjek om serveren svarede med succes (f.eks. status 200)
        if (!response.ok) {
            throw new Error("Netværksfejl eller serverfejl!");
        }
        return response.json(); // Konverterer JSON-teksten til et rigtigt JS-objekt
    })
    .then(brugerData => {
        // Her har vi adgang til dataene
        console.log(`Brugerens navn er: ${brugerData.name}`);
    })
    .catch(fejl => {
        // Hvis internettet ryger, eller URL'en er forkert, fanges fejlen her
        console.error("Der skete en fejl:", fejl);
    });
            

Moderne asynkron syntaks

Lektion 16: Moderne asynkron syntaks: Async og Await

Selvom .then() er smart, kan koden stadig blive en smule uoverskuelig, hvis du skal hente data flere steder fra i træk. Derfor introducerede JavaScript async og await. Det er blot en pænere indpakning (kaldet syntaktisk sukker), som får asynkron kode til at ligne helt almindelig, lineær kode.

Regler for async/await:

  1. Du kan kun bruge ordet await inde i en funktion, der er markeret med ordet async.
  2. await stopper midlertidigt afviklingen af funktionen, indtil dit Promise er færdigt (uden at fryse browseren).
  3. Vi bruger en traditionel try...catch-blok til at fange fejl.

Her er præcis samme opgave som før, bare skrevet på den moderne og professionelle måde:

// 1. Markér funktionen som async
const hentBruger = async () => {
    try {
        // 2. Brug await foran fetch for at vente på serversvaret
        const svar = await fetch("https://typicode.com");
        
        if (!svar.ok) {
            throw new Error(`Fejlstatus: ${svar.status}`);
        }
        
        // 3. Vent på at JSON-teksten bliver pakket ud til et objekt
        const data = await svar.json();
        
        console.log(`Succes! E-mailen er: ${data.email}`);
    } catch (fejl) {
        // Fanger alle fejl i try-blokken (både netværksfejl og manuelle fejl)
        console.error("Kunne ikke hente data:", fejl.message);
    }
};

// Kald funktionen
hentBruger();
            

Lektion 17: Send data med POST-anmodninger

Indtil nu har vi kun hentet data (GET). Hvis du skal sende data til en server (f.eks. oprette en ny bruger eller gemme et blogindlæg), skal du tilføje et ekstra indstillings-objekt til din fetch().

const opretNyBruger = async () => {
    const nyBruger = {
        title: "Mit nye indlæg",
        body: "Dette er teksten i indlægget.",
        userId: 1
    };

    try {
        const svar = await fetch("https://typicode.com", {
            method: "POST", // Definer metoden
            headers: {
                "Content-Type": "application/json; charset=UTF-8" // Fortæl serveren, at vi sender JSON
            },
            body: JSON.stringify(nyBruger) // Konverter vores JS-objekt til en rå JSON-tekststreng
        });

        const resultat = await svar.json();
        console.log("Serveren har modtaget data og oprettet elementet:", resultat);
    } catch (fejl) {
        console.error("Kunne ikke sende data:", fejl);
    }
};

opretNyBruger();
            

Del 6: Avanceret JavaScript og arkitektur

Dette modul tager dig fra at skrive løse scripts til at bygge robuste applikationer, der kan gemme data lokalt på brugerens maskine og skalere uden at blive uoverskuelige.

Lektion 18: Objektorienteret JavaScript (OOP)

I del 3 lærte du om simple objekter. Hvis du skal bygge mange objekter af samme type (f.eks. 100 forskellige fjender i et spil eller 20 varer i en webshop-kurv), bruger vi Klasser (class) som en arkitekttegning.

ES6 klasser og konstruktører
En klasse definerer, hvilke egenskaber og metoder objekterne skal have. Vi bruger ordet new til at skabe et konkret objekt ud fra klassen.

class Produkt {
    // Konstruktøren kører automatisk, hver gang vi skriver 'new Produkt()'
    constructor(navn, pris) {
        this.navn = navn;
        this.pris = pris;
    }

    // En metode (funktion) tilgængelig for alle produkter
    visPrisinfo() {
        return `${this.navn} koster ${this.pris} kr.`;
    }
}

// Opretter konkrete instanser (objekter) af klassen
const produkt1 = new Produkt("Kaffemaskine", 499);
const produkt2 = new Produkt("Brødrister", 249);

console.log(produkt1.visPrisinfo()); // Udskriver: Kaffemaskine koster 499 kr.
            

Arv (Inheritance)
Du kan lade en klasse arve fra en anden klasse, så du slipper for at skrive den samme kode to gange. Vi bruger ordet extends til at arve, og super() til at kalde forælder-klassens konstruktør.

// Forælder-klasse
class Bruger {
    constructor(navn) {
        this.navn = navn;
    }
    logInd() {
        console.log(`${this.navn} er nu logget ind.`);
    }
}

// Barn-klasse, der arver fra Bruger
class Admin extends Bruger {
    constructor(navn, rettigheder) {
        super(navn); // Kalder Bruger-klassens constructor
        this.rettigheder = rettigheder;
    }
    sletBruger(brugerNavn) {
        console.log(`Admin ${this.navn} slettede brugeren: ${brugerNavn}`);
    }
}

const adminBruger = new Admin("Søren", ["alt"]);
adminBruger.logInd(); // Virker! Udskriver: Søren er nu logget ind.
adminBruger.sletBruger("Mette");
            

Lektion 19: Browser Storage (localStorage)

Hjemmesider glemmer normalt alt, når du genindlæser siden eller lukker browseren. Hvis du vil gemme data permanent på brugerens computer (f.eks. deres foretrukne Dark Mode indstilling eller en indkøbskurv), bruger vi localStorage.

Regler for localStorage:

  1. Data gemmes direkte i browseren uden tidsbegrænsning.
  2. Man kan kun gemme rene tekststrenge (Strings).
  3. Hvis vi vil gemme objekter eller arrays, skal vi omdanne dem til en JSON-streng først.
// --- 1. Gem og hent simple tekster ---
localStorage.setItem("tema", "dark"); // Gemmer data
const valgtTema = localStorage.getItem("tema"); // Henter data
console.log(valgtTema); // Udskriver: dark

// --- 2. Gem et komplekst objekt eller array (Vigtigt!) ---
const indstillinger = { volumen: 80, sprog: "da" };

// Vi omdanner objektet til en tekststreng med JSON.stringify() før det gemmes
localStorage.setItem("bruger_indstillinger", JSON.stringify(indstillinger));

// Når vi henter det, omdanner vi tekststrengen tilbage til et JS-objekt med JSON.parse()
const gemteDataRaw = localStorage.getItem("bruger_indstillinger");
const rigtigtObjekt = JSON.parse(gemteDataRaw);

console.log(rigtigtObjekt.volumen); // Udskriver: 80

// --- 3. Sletning af data ---
localStorage.removeItem("tema"); // Sletter én ting
// localStorage.clear(); // Nulstiller og sletter ALT i localStorage for denne side
            

Lektion 20: JavaScript moduler (import / export)

Når dit projekt vokser, bliver én stor script.js fil hurtigt uoverskuelig. Moduler gør det muligt at dele din kode op i flere mindre filer. Du kan eksportere funktioner eller klasser fra én fil, og importere dem i en anden.
Bemærk: For at bruge moduler i browseren, skal du tilføje type="module" til dit <script>-tag i HTML-filen: <script src="app.js" type="module"></script>

Eksempel på modul-opdeling

1. Filen matematik.js (Vi pakker funktioner og eksporterer dem)

// Fil: matematik.js

// Brug ordet 'export' foran det, der skal kunne bruges i andre filer
export const LægSammen = (a, b) => a + b;
export const TrækFra = (a, b) => a - b;

// Man kan også lave en default export (hovedfunktionen i filen)
export default function multiplicer(a, b) {
    return a * b;
}
            

2. Filen app.js (Hovedfilen, hvor vi samler det hele)

// Fil: app.js

// Vi importerer de specifikke funktioner vha. { } samt default funktionen uden { }
import multiplicer, { LægSammen, TrækFra } from './matematik.js';

console.log(LægSammen(5, 10)); // Udskriver: 15
console.log(multiplicer(3, 4)); // Udskriver: 12
            

Del 7: Værktøjskassen og næste skridt

Dette modul klæder dig på til at træde ind i det professionelle JavaScript-økosystem. Du lærer at automatisere dit arbejde og vælge den rette vej til dine fremtidige projekter.

Lektion 21: Moderne JavaScript værktøjer

Når du bygger professionelle webapplikationer, skriver du sjældent bare rå filer, som du åbner direkte i browseren. Du bruger værktøjer til at hente eksterne kodebiblioteker (pakker) og optimere din kode til produktion.

1. Hvad er Node.js og npm?

  • Node.js: En motor, der gør det muligt at køre JavaScript direkte på din computer (i din terminal) i stedet for kun inde i en browser.
  • npm (Node Package Manager): Verdens største register af gratis kodebiblioteker. Det følger automatisk med, når du installerer Node.js. Med npm kan du downloade færdige pakker (f.eks. kalendere, animations-biblioteker eller valideringsværktøjer).

2. Byggeværktøjer: Vite
I dag bruger næsten alle udviklere et byggeværktøj (en bundler) til at køre deres projekter lokalt. Det mest populære og lynhurtige værktøj hedder Vite.
Når du bruger Vite, genindlæses din browser automatisk i det sekund, du gemmer din kode, og når du er færdig, pakker og komprimerer Vite din kode, så den fylder mindst muligt på serveren.

Trin Handling Terminalkommando
1Start et nyt projekt med Vitenpm create vite@latest mit-app -- --template vanilla
2Gå ind i projektmappencd mit-app
3Installer projektets afhængighedernpm install
4Start den lokale udviklingsservernpm run dev

3. Kvalitetssikring: ESLint & Prettier
For at sikre, at din kode er pæn og uden fejl, bruger man to uundværlige værktøjer (ofte som udvidelser i VS Code):

  • Prettier: Formaterer automatisk din kode (laver pæne indrykninger, ensartede anførselstegn og semikoloner), hver gang du gemmer.
  • ESLint: Scanner din kode live for fejl eller dårlig praksis (f.eks. hvis du har glemt at bruge en variabel, du har oprettet).

Lektion 22: JavaScript økosystemet & frameworks

Når du har helt styr på det grundlæggende JavaScript (også kaldet Vanilla JavaScript), vil du hurtigt opdage, at komplekse brugerflader (som f.eks. Facebook, Netflix eller Spotify) bliver meget svære at vedligeholde, hvis du skal opdatere DOM'en manuelt hele tiden med querySelector.
Derfor skifter man i branchen over til at bruge et frontend-framework.

De 3 store frontend-frameworks

Framework / Bibliotek Ejer / Bagmand Fordele og karakteristika Popularitet
React Meta (Facebook) Teknisk set et bibliotek. Bruger "komponenter" (små genanvendelige dele) og er det absolut mest efterspurgte værktøj på jobmarkedet. 🌟 Ekstremt høj (Markedsleder)
Vue.js Open-source (Community) Kendt for at have den nemmeste læringskurve. Det minder meget om traditionel HTML/CSS/JS og er fantastisk til både små og store projekter. 💚 Høj og elsket af udviklere
Angular Google Et gigantisk, fuldkomment framework. Det har meget stramme regler og bruges primært i store virksomheder og enterprise-løsninger. 🏢 Stabil i erhvervslivet

JavaScript på serveren: Node.js & Express
Hvis du vil være Full-Stack udvikler (både kode frontend og backend), behøver du ikke lære et nyt sprog som PHP eller Python. Du kan bruge Node.js sammen med et bibliotek, der hedder Express. Det gør det muligt at bygge dine egne webservere og REST-API'er direkte i JavaScript.

Lektion 23: Hvorfor TypeScript er din fremtid

Når du skriver store JavaScript-projekter, er en af de største kilder til fejl, at JavaScript er dynamisk typet. Hvis du har en funktion, der forventer et tal, men du ved en fejl sender en tekststreng, opdager JavaScript det først, når koden kører i browseren, og siden måske crasher for brugeren.
Her kommer TypeScript ind i billedet. TypeScript er en overbygning på JavaScript, som tilføjer stramme typer.

// I TypeScript låser vi datatypen fast (f.eks. : number)
function hilsen(alder: number) {
    console.log(`Du er ${alder} år gammel.`);
}

// Hvis du prøver at skrive dette i VS Code:
hilsen("femogtyve"); 
// Rød bølgelinje under koden MED DET SAMME! Editoren stopper dig, før du overhovedet tester i browseren.
            

I dag koder langt de fleste professionelle udviklere i TypeScript frem for ren JavaScript, fordi det fanger fejl på et splitsekund under udviklingen. Da syntaksen er 95% identisk med JavaScript, er det det absolut mest naturlige næste skridt for dig.

Afslutning: Din karriererejse herfra

Stort tillykke! Du har nu tygget dig igennem hele fundamentet for moderne webudvikling med JavaScript. For at rykke fra kursus til virkelighed, er her den anbefalede rækkefølge til din videre træning:

  1. Byg 3 små projekter i Vanilla JS: (F.eks. en To-Do app med localStorage, en lommeregner, eller en vejr-app, der henter live-data fra et gratis vejr-API med fetch).
  2. Lær Vite: Prøv at sætte dit næste projekt op via terminalen med Vite i stedet for blot at åbne en lokal HTML-fil.
  3. Vælg dit framework: Start med React eller Vue.js. Brug de officielle dokumentationer eller gratis begynder-tutorials til at forstå, hvordan komponenter fungerer.

Husk, at programmering er et håndværk – jo mere du skriver koden selv og laver fejl, jo hurtigere lærer du det!

Klar til at bygge dynamiske webløsninger?

Brug din nye viden om JavaScript til at skabe interaktive og lynhurtige webapplikationer.