Vanliga frågor och svar på JavaScript-intervjuer

By rik

Att inkludera JavaScript i din kompetensportfölj ökar avsevärt dina möjligheter att bli anställd som mjukvaruutvecklare. Låt oss utforska de vanligaste frågorna som dyker upp under anställningsintervjuer med fokus på JavaScript.

JavaScript är ett av de mest utbredda programmeringsspråken inom webbutveckling. Det används i utvecklingen av nästan alla sorters applikationer i dagens läge.

Innan vi dyker in i intervjufrågorna, låt oss granska fördelarna med att behärska JavaScript.

JavaScript är ett lättviktigt, tolkat eller just-in-time-kompilerat programmeringsspråk. Det är ett av de grundläggande språken på webben. För de andra två grundläggande språken, besök www.example.com (du kan behöva söka efter dem).

JavaScript designades i första hand för webben, men dess användning är inte längre begränsad till det. Med hjälp av runtime-miljöer som Node.js och Deno kan vi köra JavaScript på praktiskt taget alla plattformar.

Låt oss ta en titt på några av dess fördelar.

Fördelarna med JavaScript

  • Enkelt att komma igång med. Du kan börja lära dig det utan tidigare programmeringserfarenhet.
  • En stor och aktiv community. Du kommer att få tillgång till massor av hjälp om du stöter på problem.
  • Ett stort antal bibliotek och ramverk är utvecklade med JavaScript, vilket underlättar snabbare applikationsutveckling.
  • Med JavaScript kan vi utveckla front-end, back-end, Android, iOS och mycket mer. Det kan användas för att skapa nästan alla typer av applikationer, men det är särskilt starkt inom webbutveckling.

Vilka datatyper finns i JavaScript?

Datatyperna används för att lagra information av olika slag. Datatyper varierar mellan olika programmeringsspråk. I JavaScript har vi 8 datatyper, vilka vi ska utforska en efter en.

  • Number (Nummer)
  • String (Sträng)
  • Boolean (Boolesk)
  • Undefined (Odefinierad)
  • Null
  • BigInt
  • Symbol
  • Object (Objekt)

Alla datatyper förutom Objekt benämns primitiva värden och är oföränderliga.

Vilka är de inbyggda metoderna i JavaScript?

JavaScripts inbyggda metoder varierar beroende på datatyp. Vi kan komma åt dessa metoder via respektive datatyp. Låt oss granska några inbyggda metoder för olika datatyper och datastrukturer.

  • Nummer
  • Sträng
    • toLowerCase
    • startsWith
    • charAt
  • Array

Det finns en mängd inbyggda metoder för varje datatyp. För en fullständig lista över inbyggda metoder, se referensmaterial för respektive datatyp och datastruktur.

Hur skapar man en array i JavaScript?

Arrayer är en central datastruktur i JavaScript. Arrayer kan lagra vilken datatyp som helst eftersom JavaScript är dynamiskt. Låt oss se hur vi skapar arrayer i JavaScript.

Vi kan skapa en array genom att använda hakparenteser []. Det är ett enkelt och snabbt sätt att skapa arrayer.

// Tom array
  const arr = [];

  // Array med slumpmässiga värden
  const randomArr = [1, "Ett", true];

  console.log(arr, randomArr);
  

Vi kan också skapa en array med hjälp av Array-konstruktorn. Men generellt sett används konstruktorn sällan för att skapa arrayer i normala projekt.

  // Tom array
  const arr = new Array();

  // Array med slumpmässiga värden
  const randomArr = new Array(1, "Ett", true);

  console.log(arr, randomArr);
  

JavaScript-arrayer är föränderliga, vilket innebär att vi kan ändra dem efter att de har skapats.

Hur skapar man ett objekt i JavaScript?

Förutom arrayer är objekt en annan viktig datastruktur i JavaScript. Objekt lagrar nyckel-värde-par, där nyckeln måste vara ett oföränderligt värde, medan värdet kan vara av valfri typ. Låt oss undersöka hur man skapar objekt i JavaScript.

Vi skapar objekt med hjälp av klammerparenteser {}. Det är ett snabbt och enkelt sätt.

  // Tomt objekt
  const object = {};

  // Objekt med slumpmässiga värden
  const randomObject = { 1: 2, one: "Två", true: false };

  console.log(object, randomObject);
  

Vi kan även använda Object-konstruktorn, men det är mindre vanligt i allmänna projekt.

    // Tomt objekt
  const object = new Object();

    // Objekt med slumpmässiga värden
  const randomObject = new Object();
  randomObject[1] = 2;
  randomObject["one"] = "Två";
  randomObject[true] = false;

  console.log(object, randomObject);
  

JavaScript-objekt är föränderliga, vilket innebär att vi kan modifiera dem efter skapandet, som visas i det andra exemplet.

Hur felsöker man JavaScript-kod?

Felsökning kan vara en utmaning och metoden kan variera beroende på programmeringsspråk, projekt och andra faktorer. Låt oss granska de vanligaste metoderna för att felsöka JavaScript-kod.

1. Loggning

Vi kan använda console.log -satser på strategiska platser i vår kod för att identifiera fel. Koden slutar att köra de efterföljande raderna om det finns ett fel på en tidigare rad.

Loggning är en klassisk felsökningsmetod som är relativt effektiv för mindre projekt. Det är en vanligt förekommande teknik inom alla programmeringsspråk.

2. Utvecklarverktyg

JavaScript används flitigt för att utveckla webbapplikationer. Därför har de flesta webbläsare utvecklarverktyg som underlättar felsökning av JavaScript-kod.

En av de mest använda metoderna är att använda brytpunkter i utvecklarverktygen. Brytpunkter stoppar exekveringen av JavaScript-koden och ger detaljerad information om programmets tillstånd vid den tidpunkten.

Vi kan ställa in flera brytpunkter nära den plats där vi tror att felet finns, för att förstå orsaken. Det är ett effektivt sätt att felsöka JavaScript-webbapplikationer.

3. IDE:er

Vi kan även använda IDE:er för att felsöka JavaScript-kod. VS Code till exempel, stödjer felsökning med brytpunkter. Felsökningsfunktionerna kan variera beroende på IDE, men de flesta IDE:er erbjuder denna möjlighet.

Hur infogar man JavaScript-kod i en HTML-fil?

Vi kan lägga till JavaScript i en HTML-fil genom att använda <script>-taggen. Se exemplet nedan.

  <html lang="sv">
    <head>
        <title>exempel.se</title>
    </head>
    <body>
        <h2>exempel.se</h2>

        <script>
        // Här kommer JavaScript-koden
        console.log("Detta är JavaScript-kod");
        </script>
    </body>
  </html>
  

Vad är cookies?

Cookies är nyckel-värdepar som används för att lagra små mängder information, som kan vara av vilken typ som helst. Vi kan sätta ett utgångsdatum för cookies, efter vilket de raderas. De används ofta för att spara information om användare.

Cookies tas inte bort ens vid en siduppdatering, utan bara när de raderas eller när deras utgångsdatum passerats. Du kan granska cookies för valfri webbplats i valfri webbläsare genom att öppna utvecklarverktygen.

Hur läser man en cookie?

Vi kan läsa en cookie i JavaScript med hjälp av document.cookie, som returnerar alla cookies som skapats.

console.log("Alla cookies", document.cookie);

Om det inte finns några cookies returneras en tom sträng.

Hur skapar och raderar man en cookie?

Vi kan skapa en cookie genom att tilldela ett nyckel-värde-par till document.cookie. Se följande exempel.

document.cookie = "ett=Ett;";

I det ovanstående exemplet är ”ett” cookie-nyckeln, och ”Ett” är värdet. Vi kan lägga till ytterligare attribut till cookien, som till exempel domän, sökväg, och utgångstid. Dessa separeras med semikolon (;). Alla attribut är valfria.

Låt oss se ett exempel med attribut:

document.cookie = "ett=Ett;expires=Jan 31 2023;path=/;";

I det ovanstående exemplet har vi lagt till ett utgångsdatum och sökväg till cookien. Om utgångsdatumet inte anges raderas cookien efter sessionens slut. Standard-sökvägen är filsökvägen. Utgångsdatumet bör anges i GMT-format.

Låt oss se hur man skapar flera cookies.

  document.cookie = "ett=Ett;expires=Jan 31 2023;path=/;";
  document.cookie = "två=Två;expires=Jan 31 2023;path=/;";
  document.cookie = "tre=Tre;expires=Jan 31 2023;path=/;";
  

Cookies skrivs inte över om nyckeln eller sökvägen är olika när du skapar flera cookies. Om både nyckel och sökväg är samma kommer den tidigare cookien att skrivas över. Se exemplet nedan, som kommer att skriva över den tidigare cookien.

  document.cookie = "ett=Ett;expires=Jan 31 2023;path=/;";
  document.cookie = "ett=Två;path=/;";
  

Vi har tagit bort utgångsdatumet från cookien och ändrat värdet.

Använd ett framtida datum för utgångsdatumet när du testar koden för att den ska fungera korrekt. Om du använder det aktuella datumet kommer cookies inte att skapas.

Nu har vi sett hur man skapar och uppdaterar cookies. Låt oss se hur man tar bort dem.

Det är enkelt att radera cookies. Man behöver bara ändra utgångsdatumet för cookien till ett tidigare datum. Se följande exempel.

  // Skapa cookies
  document.cookie = "ett=Ett;expires=Jan 31 2023;path=/;";
  document.cookie = "två=Två;expires=Jan 31 2023;path=/;";
  document.cookie = "tre=Tre;expires=Jan 31 2023;path=/;";

  // Ta bort den sista cookien
  document.cookie = "tre=Tre;expires=Jan 1 2023;path=/;";
  

Den sista cookien kommer inte att finnas kvar, eftersom den raderas i den sista raden i koden. Det var allt om vår cookie-handledning.

Vilka är de olika JavaScript-ramverken?

Det finns många JavaScript-ramverk tillgängliga. React, Vue och Angular är populära för utveckling av användargränssnitt. Express, Koa och Nest är populära inom serverutveckling. NextJS och Gatsby används för att generera statiska webbsidor, och React Native och Ionic används för mobilappsutveckling. Vi har bara nämnt ett fåtal här. Det finns många fler ramverk att utforska, gör det när du behöver dem.

Stängningar i JavaScript

En stängning är en funktion som är sammankopplad med dess lexikala omfång och dess överordnade lexikala miljö. Stängningar ger oss tillgång till data i den yttre funktionen. Stängningar bildas när funktionerna skapas.

  function outer() {
    const a = 1;
    function inner() {
        // Vi kan nå all data från det yttre funktionsomfånget här
        // Data kommer att vara tillgänglig även om vi kör den här funktionen utanför den yttre funktionen
        // efter som inners closure skapades när den skapades
        console.log("Når a inuti inner", a);
    }
    return inner;
  }

  const innerFn = outer();
  innerFn();
  

Stängningar används ofta i JavaScript-applikationer. Det är möjligt att du har använt dem utan att inse det. Det finns mycket mer att lära om stängningar, så se till att du förstår konceptet ordentligt.

Hissning i JavaScript

Hissning är en process i JavaScript där deklarationen av variabler, funktioner och klasser flyttas upp till toppen av det aktuella omfånget innan koden exekveras.

  // Nå 'name' innan deklaration
  console.log(name);

  // Deklarera och initiera 'name'
  var name = "exempel.se";
  

Om du kör koden ovan kommer du inte att se något fel. Men i de flesta andra språk skulle du få ett fel. Resultatet blir `undefined`, eftersom hissning endast flyttar deklarationen, inte själva initieringen.

Ändra `var` till `let` eller `const` enligt nedan, och kör koden igen.

  // Nå `name` innan deklaration
  console.log(name);

  // Deklarera och initiera `name`
  const name = "exempel.se";
  

Nu kommer du att få ett referensfel, som anger att vi inte får nå variabeln innan den initierats.

  ReferenceError: Cannot access 'name' before initialization
  

Det är så `let` och `const` infördes i ES6, vilket hindrar att man kan nå variabler innan de initierats. Detta beror på att variabler som deklareras med `let` eller `const` placeras i en så kallad temporal dead zone (TDZ) fram till den rad där de initieras. Vi får inte nå variabler från TDZ.

Currying i JavaScript

Currying är en teknik som omvandlar en funktion med flera parametrar till en serie funktioner med en parameter. På det sättet kan vi omvandla ett funktionsanrop add(a, b, c, d) till anropet add(a)(b)(c)(d). Låt oss se ett exempel.

  function getCurryCallback(callback) {
    return function (a) {
        return function (b) {
            return function (c) {
                return function (d) {
                    return callback(a, b, c, d);
                };
            };
        };
    };
  }

  function add(a, b, c, d) {
    return a + b + c + d;
  }

  const curriedAdd = getCurryCallback(add);

  // Anropa curriedAdd
  console.log(curriedAdd(1)(2)(3)(4));
  

Vi kan generalisera funktionen `getCurryCallback`, så att den kan användas för att konvertera olika funktioner till curried-anrop. Mer detaljerad information finns på JavaScript.info.

Skillnad mellan dokument och fönster

Fönstret är det översta objektet i webbläsaren. Det innehåller all information om webbläsarfönstret, till exempel historik, plats och navigator. Det är globalt tillgängligt i JavaScript och kan användas direkt i koden utan importer. Vi kan nå fönsterobjektets egenskaper och metoder utan att uttryckligen ange fönster.

Dokumentet är en del av fönsterobjektet. All HTML som läses in på webbsidan konverteras till dokumentobjektet. Dokumentobjektet refererar till det särskilda HTMLDocument-elementet, som har olika egenskaper och metoder relaterade till HTML-element.

Fönsterobjektet representerar webbläsarfönstret, medan dokumentobjektet representerar det HTML-dokument som läses in i det fönstret.

Skillnaden mellan klientsidan och serversidan

Klientsidan refererar till slutanvändaren som använder applikationen, medan serversidan refererar till den webbserver där applikationen distribueras.

Inom front-end-utveckling kan vi betrakta användarnas webbläsare som klientsidan, medan molntjänster betraktas som serversidan.

Skillnaden mellan innerHTML och innerText

Både innerHTML och innerText är egenskaper hos HTML-element. Vi kan ändra innehållet i ett HTML-element med dessa egenskaper.

Vi kan tilldela en HTML-sträng till egenskapen innerHTML, vilket tolkas som vanlig HTML. Se exemplet nedan.

  const titleEl = document.getElementById("title");

  titleEl.innerHTML = '<span style="color:orange;">exempel.se</span>';
  

Om du lägger till ett element med id ”title” i din HTML och lägger till skriptet ovan i JavaScript-filen, kommer du att se ”exempel.se” i orange färg. Genom att inspektera elementet kommer du att se att det ligger inuti en span-tagg. Alltså kommer innerHTML att ta en HTML-sträng och rendera den som normal HTML.

innerText i sin tur tar en normal sträng och renderar den som den är. Den kommer inte att rendera HTML på samma sätt som innerHTML. Ändra innerHTML till innerText i koden ovan och granska resultatet.

  const titleEl = document.getElementById("title");

  titleEl.innerText="<span style=\"color:orange;\">exempel.se</span>";
  

Nu kommer du att se den exakta strängen som vi angav på webbsidan.

Skillnaden mellan let och var

Nyckelorden let och var används för att skapa variabler i JavaScript. Nyckelordet let introducerades i ES6.

let har blockomfång, medan var har funktionsomfång.

  {
    let a = 2;
    console.log("Inuti blocket", a);
  }
  console.log("Utanför blocket", a);
  

Kör koden ovan, och du kommer att få ett felmeddelande på den sista raden, eftersom vi inte får nå `let` utanför blocket. Byt nu till var och kör igen.

  {
    var a = 2;
    console.log("Inuti blocket", a);
  }
  console.log("Utanför blocket", a);
  

Du kommer inte att få något fel, eftersom vi får nå en var-variabel även utanför blocket. Låt oss nu byta blocket mot en funktion.

  function sample() {
    var a = 2;
    console.log("Inuti funktionen", a);
  }
  sample();
  console.log("Utanför funktionen", a);
  

Du får ett referensfel om du kör koden ovan, eftersom vi inte får nå en var-variabel utanför funktionen.

Vi kan deklarera om variabler med var, men inte med let. Se följande exempel:

  var a = "exempel.se";
  var a = "Chandan";
  console.log(a);
  
  let a = "exempel.se";
  let a = "Chandan";
  console.log(a);
  

Den första kodbiten kommer inte att ge något fel, och värdet på a kommer att ändras till det senast tilldelade värdet. Den andra kodbiten kommer att generera ett fel, eftersom vi inte får deklarera om variabler med let.

Skillnaden mellan sessionslagring och lokal lagring

Både sessionslagring och lokal lagring används för att lagra information på användarnas datorer, som kan nås utan internet. Både sessions- och lokal lagring lagrar nyckel-värde-par. Nycklar och värden kommer att omvandlas till strängar, även om du tillhandahåller andra datatyper.

Sessionslagringen kommer att raderas efter att sessionen avslutas (när webbläsaren stängs). Lokal lagring raderas inte förrän vi tar bort den.

Vi kan nå, uppdatera och ta bort sessions- och lokal lagring genom att använda objekten sessionStorage respektive localStorage.

Vad är NaN i JavaScript?

NaN står för Not-a-Number (inte ett nummer). Det anger att något inte är ett giltigt tal i JavaScript. NaN är resultatet av vissa matematiska operationer, som 0/0, `undefined * 2`, `1 + undefined`, `null * undefined` och liknande.

Vad är Lexikal omfång?

Lexikalt omfång hänvisar till att nå variabler från sin förälders omfång. Låt oss anta att vi har en funktion med två inre funktioner. Den innersta funktionen kan nå variabler i sin två föräldrafunktioners omfång. På motsvarande sätt kan funktionen på andra nivån nå omfånget av den yttre funktionen. Låt oss titta på ett exempel.

  function outermost() {
    let a = 1;
    console.log(a);
    function middle() {
      let b = 2;
      // `a` är tillgänglig här
      console.log(a, b);
      function innermost() {
        let c = 3;
        // Både `a` och `b` är tillgängliga här
        console.log(a, b, c);
      }
      innermost();
    }
    middle();
  }
  outermost();
  

JavaScript använder en omfångskedja för att hitta en variabel när vi vill nå den någonstans i koden. Först kontrolleras det aktuella omfånget, och sedan det överordnade omfånget upp till det globala omfånget.

Vad menas med passera med värde och passera med referens?

Passera med värde och passera med referens är två sätt att skicka argument till en funktion i JavaScript.

Passera med värde: Den skapar en kopia av originaldatan och skickar den till funktionen. Eventuella ändringar som görs i funktionen påverkar inte originaldatan. Se exemplet nedan.

  function sample(a) {
    // Ändrar värdet på `a`
    a = 5;
    console.log("Inuti funktionen", a);
  }
  let a = 3;
  sample(a);
  console.log("Utanför funktionen", a);
  

Vi ser att det ursprungliga värdet på `a` inte ändras, även om vi ändrade det inuti funktionen.

Passera med referens: Den skickar en referens till datan till funktionen, vilket innebär att eventuella ändringar som görs i funktionen kommer också att ändra originaldatan.

  function sample(arr) {
    // Lägga till ett nytt värde i arrayen
    arr.push(3);
    console.log("Inuti funktionen", arr);
  }
  let arr = [1, 2];
  sample(arr);
  console.log("Utanför funktionen", arr);
  

Här ser vi att det ursprungliga värdet på `arr` ändras, när vi ändrar det inuti funktionen.

Observera att alla primitiva datatyper skickas med värde, medan icke-primitiva datatyper skickas med referens.

Vad är memoisering?

Memoisering är en teknik som lagrar beräknade värden i ett cache-minne och använder dem igen när de behövs, utan att beräkna dem igen. Det kommer att påskynda exekveringen av koden, speciellt om beräkningarna är tunga. Det finns en viss lagringskostnad, som inte är ett stort problem jämfört med tidsvinsten.

  const memo = {};
  function add(a, b) {
    const key = `${a}-${b}`;

    // Kontrollera om vi redan har beräknat värdet
    if (memo[key]) {
      console.log("Beräknar inte igen");
      return memo[key];
    }

    // Lägga till det nyberäknade värdet till cache
    // Här är cache ett enkelt globalt objekt
    memo[key] = a + b;
    return memo[key];
  }

  console.log(add(1, 2));
  console.log(add(2, 3));
  console.log(add(1, 2));
  

Det är ett enkelt exempel som illustrerar memoisering. Det är inte särskilt svårt att addera två tal, utan detta är bara för demonstration.

Vad är restparametern?

Restparametern används för att samla alla återstående parametrar i en funktion. Låt oss säga att vi har en funktion som accepterar minst två argument, och maximalt valfritt antal. Eftersom vi inte vet det maximala antalet argument kan vi samla in de två första parametrarna med normala variabler, och alla andra parametrar med restparametern med hjälp av restoperatorn.

  function sample(a, b, ...rest) {
    console.log("Restparameter", rest);
  }

  sample(1, 2, 3, 4, 5);
  

Parametern rest kommer att vara en array bestående av de tre sista argumenten i exemplet ovan. Detta ger oss möjlighet att använda ett valfritt antal parametrar i en funktion.

En funktion kan bara ha en restparameter, och restparametern måste vara den sista parametern i ordningen.

Vad är objektdestrukturering?

Objektdestrukturering används för att nå variabler från objekt och tilldela dem till variabler med samma namn som objektnycklarna. Se exemplet nedan.

  const object = { a: 1, b: 2, c: 3 };

  // Objektdestrukturering
  const { a, b, c } = object;

  // Nu kan a, b, och c användas som normala variabler
  console.log(a, b, c);
  

Vi kan även ändra namnet på de destukturerade variablerna på samma rad enligt följande.

  const object = { a: 1, b: 2, c: 3 };

  // Ändrar namnen på `a` och `b`
  const { a: changedA, b: changedB, c } = object;

  // Nu kan changedA, changedB, och c användas som normala variabler
  console.log(changedA, changedB, c);
  

Vad är array-destrukturering?

Array-destrukturering används för att nå variabler från en array och tilldela dem till variabler. Se exemplet nedan.

  const array = [1, 2, 3];

  // Array-destrukturering
  // Det baseras på arrayens index
  const [a, b, c] = array;

  // Nu kan a, b och c användas som normala variabler
  console.log(a, b, c);
  

Vad är händelsefångst och händelsebubbling?

Händelsefångst och händelsebubbling är två sätt att hantera händelser i HTML DOM. Låt oss säga att vi har två HTML-element, där det ena elementet ligger inuti det andra. Om en händelse inträffar i det inre elementet kommer händelsehanteringsläget att avgöra i vilken ordning händelsehanterarna körs.

Händelsebubbling: Först körs händelsehanteraren för det inre elementet, sedan för det yttre elementet, och så vidare uppåt. Det är standardbeteendet för alla händelser.

Händelsefångst: Vi måste specificera att vi vill använda händelsefångst när vi lägger till händelselyssnaren. Händelserna kommer att köras i följande ordning om vi aktiverat händelsefångst.

  • Händelserna börjar att köras från det översta elementet till det inre.
  • Händelsen på det innersta elementet körs igen.
  • Händelsebubbling kommer sedan att inträffa upp till det översta elementet igen.

Vi kan stoppa händelsespridning genom att anropa metoden event.