Informatikbog HHX

  • 🗚
  • 🔍︎
  • JavaScript #

    Dette kapitel indeholder en hurtig introduktion til JavaScript-sproget.

    JavaScript er et programmeringssprog.

    Der findes tusindvis a programmeringssprog i verden. JavaScript-sproget er valgt til denne bog, fordi det er indbygget i alle webbrowsere (Safari og Chrome, etc.).

    Det er anstrengende at udtrykke sig, så computeren kan forstå det.

    Man bruger programmeringssprog til at gøre det lettere at producere koder, som computeren kan udføre.

    Koder i et programmeringssprog kaldes kildekode.

    Koder som computeren kan udføre, kaldes computerprogrammer.

    Browseren indeholder et fortolkerprogram, som kan udføre JavaScript-kildekode.

    åbn udviklervæktøjerne

    åbne udviklerværktøjerne i Safari.

    I Chrome taster du på Windows F12 eller Ctrl-Shift-C.

    På mac'en taster du ⌥-⌘-I.

    Første gang man kigger på computerkode, ser det uforståeligt ud.

    Kildekode er bare tekst. Nogle gange præsenteres teksten med farver, som fremhæver strukturen i kode.

    For at begynde med at læse kildekode lærer man først syntaks. Det vil sige at adskille syntaks fra navne og data.

    Navne er kildekodens semantiske indhold.

    Syntaks anvendes til at udtrykke processer og strukturer.

    De syntaktiske regler for computersprog er typisk mere komplekse end de naturlige sprog.

    På dansk kan man slippe afsted med at bruge . og ,. På JavaScript-sproget bruger man mange flere tegn or specielle ord til at udtrykke formålet med programmet.

    Til gengæld er programmeringssprogets syntaktiske regler ubrydelige og det gør det meget nemmere at lære et programmeringssprog, end at lære et naturligt sprog.

    Et program skrevet på JavaScript-sproget, er en blok af sætninger, som computeren udfører, når den kører programmet.

    Her er et eksempel på JavaScript-kode:

    window.addEventListener("DOMContentLoaded", function() {
      let naa = document.querySelector("#naa");
      let g = document.querySelector("#g");
      let pg = document.querySelector("#pg");
      let btn = document.querySelector("#sugarrush");
      btn.addEventListener("click", function() {
          pg.value = sugarrush(Number.parseInt(naa.value), Number.parseInt(g.value));
      });
    });
    

    Sætninger #

    Sætninger adskilles med semikoloner ;. Sætninger er kontrolstrukturer, erklæringer eller udtryk.

    De ord, som er fremhævet med lilla skrift, er reserverede ord og indbyggede navne. Reserverede ord bruger man til erklæringer og operatorer.

    Værdier #

    En værdi er en talmængde, som repræsenterer en del af programmets tilstand.

    Anden virkning #

    Det et program gør, er at læse input og give et output.

    Når et program interagerer med omverdenen på en anden måde (f.eks. ved at tegne en figur på skærmen) så siger man, at det har en anden virkning (side effect).

    At udregne værdien af det matematiske udtryk 2 + 2 har ingen anden virkning end at give resultatet 4.

    At give værdien af udtrykket 2 + 2 navnet x har en anden virkning, hvilket vil sige, at sætningen ændrer på noget, som hverken er input eller output (altså navnet x).

    x = 2 + 2;
    

    Erklæringer #

    En erklæring begynder med et reserveret ord og opretter på en eller anden måde et eller flere navne.

    Erklæringer har ikke en værdi - i stedet for har de en virkning (med undtagelse af erklæringen function, som har både virkning og værdi).

    De reserverede ord som er erklæringer, er blandt andet function, let, async function.

    Udtryk #

    Et udtryk er en kombination af literale og symbolske værdier og operatorer, som kan reduceres til en enkelt værdi, f.eks. 2 + 2.

    Operatorer #

    Operatorer er dele af udtryk. Det vil sige, at de giver en værdi, men har ikke nogen virkning (med undtagelse af =, ++, mfl., som både har en værdi og en virkning).

    Nogle af operatorene er +, -, *, /, <, >, ! og =, som ligner dem fra matematik.

    Specialtegn #

    Tegnene {}()[].,;:'"\ og blanktegn (mellemrum og linjeskift) kalder man specialtegn og de har hver især forskellige særlige betydninger:

    Blanktegn #

    Blanktegn adskiller navne og reserverede ord.

    De reserverede ord og specialtegnene er strukturelle, de er ligesom en slags punktummer og kommaer, som forfatteren (programmøren) bruger til at danne sætninger.

    Navne er ord, som udtrykker meningen eller hensigten med programmet.

    Navne er symbolske dataværdier, som repræsenterer en del af tilstanden i programmet.

    Komma #

    Kommaet adskiller elementer i lister

    x,y,z
    

    Anførselstegn #

    Anførselstegn (" eller ') afgrænser literale tekstværdier computerkoden. En tekstværdi er en liste af tal, computeren fortolker som bogstaver ud fra en tegntabel.

    En tekstværdi kalder man også for en streng (af bogstaver).

    "dette er ikke en instruktion til computeren, men en dataværdi."
    

    Hvis man vil bruge et anførselstegn i en tekststreng kan man "bryde ud" (escape) den normale fortolkning af koden med et \-tegn eller ved at bruge et alternativt anførselstegn til at afgrænse strengen.

    "denne streng indeholder et \"-tegn."
    'denne streng indeholder et "-tegn'
    "denne streng indeholder et '-tegn"
    'denne streng indeholder et \'-tegn'
    

    Navne kaldes også variable.

    Et navn må ikke begynde med et tal, må ikke indeholde specialtegn og må ikke være et reserveret ord.

    Navne skal erklæres, før de kan bruges. Navne kan erklæres på forskellige måder: som frie variable, som funktionsnavne og som parametre til funktioner.

    Frie variable #

    En fri variabel er en variabel, som ikke er bundet. Frie variable erklæres med de reserverede ord var, let eller const.

    let x;
    let y = 3;
    

    Virkningen af erklæringerne ovenfor er, at x har værdien undefined og y har værdien 3.

    At en variabel er fri, betyder at den er synlig på tværs af en funktionsgrænseflade uden at være en del af parameterlisten eller de lokale variable.

    Lokale variable #

    En lokal variabel er en variabel, som kun er synlig i den blok, den er erklæret.

    let a = 1;
    {
        let a = 2;
        {
            console.log('a inde i blokken =', a);
        }
    }
    console.log('a uden for blokken= ', a);
    

    Man kan også sige, at variablen a kun er synlig i det omgivende leksikalske omfang.

    Globale variable #

    En global variable er en variabel, som er synlig overalt i programmet.

    {
        {
            {
                var a = 1;
            }
        }
    }
    console.log('a =', a);
    

    Bundne variable #

    En bundet variabel er en variabel, som optræder i parameterlisten til en funktion.

    function f(x, y) {
        console.log('bundne variable i f =', x, y);
    }
    

    Krølleparenteser #

    Krølleparenteser ({}) afgrænser både definitioner af kodeblokke og literale objekter.

    Blokke #

    En blok er en sekvens af sætninger i et program.

    Sekvensen er den mest grundlæggende kontrolstruktur.

    En sætning markerer et tilstandsskift programmet.

    Sætninger i en blok adskilles med tegnet ;.

    {
        {
            {
                (2 + 3) / 5;
            }
        }
    }
    

    Blokke kan indlejres i hinanden; på den måde skaber man struktur.

    I eksemplet ovenfor er der et udtryk indeni en blok, indeni en blok, indeni en blok. Udtrykket er en sætning og giver en værdi, men ændrer ikke på processens tilstand (som er Chrome- eller Safari-app'en).

    Objekter #

    Objekter er datastrukturer, som associerer et sæt dataværdier med et sæt andre dataværdier.

    En associering af én dataværdi til én anden dataværdi kaldes for et nøgle- og værdipar.

    I et objekt findes der kun én værdi for hver nøgle, men objektet kan have mange forskellige nøgler med den samme værdi.

    en liste af navne- og værdipar

    Et literalt objekt er en blok, der skrives som en sekvens af nøgle- og værdipar, adskilt med komma.

    let x = {
        "felt1": 123,
        "en anden nøgle": 2000,
    };
    

    Man kalder også nøgle- og værdipar for felter.

    I eksemplet ovenfor erklæres navnet x og sættes til værdien af det literale objekt, som følger efter =.

    Bemærk, at der bruges et kolon og ikke et lighedstegn mellem nøgle og værdi i et objekts felter.

    Virkningen af erklæringen ovenfor er, at navnet x henviser til et objekt, som har 2 felter: felt1 og en anden nøgle.

    Kantede parenteser #

    Kantede parenteser ([]) afgrænser både literale lister af dataværdier og beregnede nøgler i objekter og fungerer som accessor til lister (og tekststrenge) og objekter.

    Accessorfunktion #

    En accessor er en funktion, der tager en datastruktur og en nøgle som input og giver et enkelt element i datastrukturen som output.

    Lister #
    let x = [3, 2, 1];
    let y = x[0];
    

    I eksemplet ovenfor henviser x til en liste af tal. Navnet y henviser til det første element (indeks 0) i listen x. Accessorfunktionen er [] og argumenterne er (x, 0).

    Objekter #
    let x = {
        "a": 3,
        "b": 2,
        "c": 1,
    };
    let y = x.a;
    let z = x["b"];
    

    I eksemplet ovenfor henviser x til et objekt med 3 felter. Navnet y henviser til værdien af det felt i objektet x, som har navnet a og navnet z henviser til værdien af det felt i objektet x, som har navnet b.

    Accessorfunktionen er for objekter enten [] eller . og argumenterne er hhv. (x, "a") og (x, "b"). Punktumsformen er en mere praktisk syntaks end kantet-parentes-formen, men dur kun med nøgler, som er gyldige navne.

    Beregnet nøgle #

    En beregnet nøgle er et dynamisk udtryk i stedet for en literal nøgle:

    function f() { return "b"; }
    let x = {
        a: 3,
        [f()]: 2,
    };
    let y = x[f()];
    

    I eksemplet ovenfor henviser x til et objekt med 2 felter. Navnet på det ene felt er output-værdien af funktionen f. Navnet y henviser til værdien af det felt.

    Almindelige parenteser #

    Almindelige parenteser (()) afgrænser både udtryk og parameterlister til funktioner.

    Et udtryk er en kombination af værdier, operatorer, funktionskald og andre udtryk.

    Et udtryk i en parentes betragtes som en enhed (en enkelt værdi).

    let x = (2 + 3) / 4;
    

    En parameterliste er en kommasepareret liste med navne, som bliver bundet til dataværdier (input), når man kalder en funktion.

    function f(a, b) {
        return a + b;
    }
    console.log('f:', f(2, 2));
    

    Tilstand #

    Tilstanden i et program er de data, som programmet arbejder på.

    Et navn er en reference til en dataværdi.

    Et navn hvis værdi kan ændre sig, kalder man for en variabel ellers er det en konstant.

    Programmøren udtrykker tilstanden i et program ved at finde på datastrukturer, som hun giver navne.

    Programmøren kan bruge alle navne, som ikke begynder med et tal, som ikke indeholder specialtegn og som ikke er reserverede ord.

    Programmet i sin helhed beskriver, hvordan man går fra en starttilstand til en sluttilstand (input til output).

    Valget af navne til datastrukturer hjælper med at afkode programkoden.

    Funktioner #

    En funktion er en logisk proces, som transformerer input til output.

    Funktioner er en form for kontrolstruktur, som gør det mulig at anvende processer som skabeloner for en eller flere dataværdier.

    Når man erklærer en funktion, beskriver man "hullerne" i skabelonen som en liste af navne, man kalder en parameterliste.

    function f(x, y) {
        let output = x + y;
        return output;
    };
    

    Erklæringen ovenfor består af det reserverede ord function, et navn på funktionen f, en parameterliste (x, y) fulgt af en blok ({ … }), som definerer funktionen.

    Navnet f er valgt tilfældigt.

    Navnene på "hullerne" i skabelonen, x og y, er også valgt tilfældigt.

    Output fra funktionen angives med det reserverede ord return efterfulgt af et udtryk (en dataværdi).

    Når man udfører funktionen, angiver man input til funktionen med en liste af dataværdier, som man kalder argumenter.

    f(2, 2);
    

    Sætningen ovenfor består af navnet f (som vi har brugt til funktionen f) og en liste af værdier i parentes.

    Når en funktionsværdi efterfølges af en parentes, så vil computeren udføre funktionen. Det vil sige, at funktionen er den næste proces, som udføres. Input til funktionen er værdierne i parentes.

    Værdien af udtrykket ovenfor er resultatet af at udføre sætningerne i definitionsblokken, hvor navnene i parameterlisten, x og y, henviser til værdierne 2 og 2.

    En operator er et andet ord for en funktion, som skrives på en særlig måde. Funktioner som f.eks. plus(x, y) og minus(x, y) er operatorer, som skrives x + y og x - y.

    Input til er operator kalder man for operander.

    Synlighed #

    Blokke har et omfang, som er afgrænset af tegnene { og }.

    Omfanget af en blok begrænser synligheden af de navne, som erklæres inde i blokken.

    At et navn er synligt, betyder, at det refererer til en dataværdi.

    Navne kan skygge for hinanden, hvis de erklæres i blokke, som er indlejret i hinanden.

    let a = 1;
    {
        let a = 2;
        {
            let a = 3;
        }
        console.log('a =', a);
    }
    

    Lukninger #

    I JavaScript danner funktionserklæringer lukninger (på engelsk closure).

    Når man erklærer en funktion, vil navne i den omgivende lukning blive indfanget og bundet til navne, som henviser til kopier af værdierne i den omgivende lukning:

    function denne_funktion_danner_en_lukning(x) {
        return function denne_funktion_har_adgang_til_lukningen(y) {
            return x + y;
        };
    }
    let f = denne_funktion_danner_en_lukning(2);
    console.log('output fra f er', f(2));
    

    Koden ovenfor er et eksempel på lukninger og andenordensfunktioner.

    I eksemplet erklæres en funktion, som giver en ny funktion som output.

    Det kaldes en andenordensfunktion, når en proces skaber en anden proces.

    Når en andenordensfunktion giver en funktion som output, kalder man det for en tredjeordensfunktion, og så videre.

    Evaluering #

    Evaluering (eller fortolkning) af programkode følger en simpel model og med kendskab til ovenstående begreber, kan man forklare simple programmer.

    Evaluering af programkode afhænger af konteksten. Konteksten er resultatet af den kode som computeren har læst og udført indtil videre - det kan være en lang række af værdier.

    Konteksten kan man forestille sig som toppen af en stak af dataværdier, som man har in mente.

    Computeren læser fra venstre mod højre.

    Når computeren læser en erklæring, vil den udføre erklæringen.

    Når computeren læser et udtryk, vil den prøve at reducere udtrykket til en enkelt dataværdi.

    Start forfra med at læse dette kapitel.

    Informationssøgning #

    JavaScript-sproget er beskrevet i en specifikation (ECMAScript® 2025 Language Specification), som udgives af organisationen ECMA International.