Skip to content
Laviyx Learn

Try

JavaScript Interview Questions

Frequently asked JavaScript interview questions on types, equality, scope, closures, this, the event loop, promises, async/await, the DOM and coding challenges, with hints, tested answers and the reasoning interviewers look for.

14 questions · Updated

  1. 1.What is the difference between var, let and const?

    BeginnerConceptVariables
    Show hint

    Scope, hoisting and reassignment.

    Show solution

    var is function-scoped and hoisted as undefined. let and const are block-scoped and throw a ReferenceError if used before their declaration (the temporal dead zone). const cannot be reassigned, though objects it holds can still be modified. Use const by default, let when the value changes.

  2. 2.What is the difference between == and ===?

    BeginnerOutput predictionTypes
    Show hint

    One converts types first.

    Show solution

    === compares type and value without conversion; == converts types first:

    JavaScript
    console.log(0 == "", 0 === "", null == undefined, null === undefined);
    Output
    true false true false

    Use === (and value == null only as a deliberate check for both null and undefined).

  3. 3.Which values are falsy in JavaScript?

    BeginnerConceptTypes
    Show hint

    There are eight.

    Show solution

    false, 0, -0, 0n, "", null, undefined and NaN. Everything else is truthy, including "0", [] and {}.

  4. 4.What is a closure? Give an example.

    IntermediateCodingFunctions
    Show hint

    A function that remembers variables from where it was created.

    Show solution

    A closure is a function together with the variables of the scope it was created in, which it keeps using after that scope has finished:

    JavaScript
    function counter() {
      let count = 0;
      return () => ++count;
    }
    const next = counter();
    next();
    console.log(next());
    Output
    2

    Closures give private state, function factories and callbacks that remember context.

  5. 5.What does this print, and how do you fix it?

    IntermediateOutput predictionScope
    Show hint

    How many variables called i are there?

    Show solution
    JavaScript
    const fns = [];
    for (var i = 0; i < 3; i++) fns.push(() => i);
    console.log(fns.map((f) => f()));
    Output
    [ 3, 3, 3 ]

    var creates one shared i, which is 3 when the functions run. With let, each iteration gets its own binding and the result is [ 0, 1, 2 ].

  6. 6.How is the value of this determined?

    IntermediateConceptthis
    Show hint

    It depends on how the function is called.

    Show solution

    obj.method() sets this to obj; a plain call fn() gives undefined in strict mode; new Fn() gives the new object; call, apply and bind set it explicitly; arrow functions have no own this and use the surrounding one.

  7. 7.Predict the output of this event loop code.

    IntermediateOutput predictionAsync
    Show hint

    Synchronous code, then microtasks, then tasks.

    Show solution
    JavaScript
    console.log("A");
    setTimeout(() => console.log("B"), 0);
    Promise.resolve().then(() => console.log("C"));
    console.log("D");
    Output
    A
    D
    C
    B

    Promise callbacks are microtasks and run before the next timer task.

  8. 8.What is the difference between Promise.all, allSettled, race and any?

    IntermediateConceptAsync
    Show hint

    When does each one resolve or reject?

    Show solution

    all resolves with every value when all fulfil and rejects on the first rejection. allSettled waits for all and reports each status. race settles with the first promise to settle. any resolves with the first fulfilment and rejects only if all reject.

  9. 9.How do you handle errors with async/await?

    IntermediateConceptAsync
    Show hint

    A rejected promise throws at await.

    Show solution

    Wrap await calls in try...catch (with finally for cleanup). A rejected promise throws at the await. For independent operations, use await Promise.all([...]) or Promise.allSettled to handle several results. Remember that fetch does not reject on HTTP errors, so check response.ok.

  10. 10.What is event delegation?

    IntermediateConceptDOM
    Show hint

    Events bubble.

    Show solution

    Instead of a listener on every child, put one listener on a parent and use event.target.closest(selector) to find which child was involved. It works because events bubble up, handles elements added later, and uses fewer listeners.

  11. 11.What is the difference between a shallow and a deep copy?

    IntermediateOutput predictionObjects
    Show hint

    What happens to nested objects?

    Show solution
    JavaScript
    const original = { tags: ["js"] };
    const shallow = { ...original };
    const deep = structuredClone(original);
    shallow.tags.push("css");
    console.log(original.tags, deep.tags);
    Output
    [ 'js', 'css' ] [ 'js' ]

    Spread copies only the top level; nested objects are shared. structuredClone copies everything.

  12. 12.Implement a debounce function.

    AdvancedCodingFunctions
    Show hint

    Clear the previous timer on every call.

    Show solution
    JavaScript
    function debounce(fn, ms) {
      let timer;
      return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => fn(...args), ms);
      };
    }
    
    const log = debounce((q) => console.log("search", q), 30);
    log("j");
    log("js");
    Output
    search js

    Only the last call within the wait time runs, which is ideal for search-as-you-type.

  13. 13.Explain the prototype chain.

    AdvancedConceptObjects
    Show hint

    Where does array.push come from?

    Show solution

    Every object links to a prototype. When a property is missing on the object, JavaScript looks it up the chain (array → Array.prototype → Object.prototype → null). Shared methods live on prototypes. Classes are syntax over this mechanism: methods go on Class.prototype, and extends links prototypes.

  14. 14.Return the indexes of the two numbers that add up to a target.

    IntermediateCodingAlgorithms
    Show hint

    Remember the numbers you have already seen.

    Show solution
    JavaScript
    function twoSum(nums, target) {
      const seen = new Map();
      for (let i = 0; i < nums.length; i++) {
        if (seen.has(target - nums[i])) return [seen.get(target - nums[i]), i];
        seen.set(nums[i], i);
      }
      return null;
    }
    console.log(twoSum([2, 7, 11, 15], 9));
    Output
    [ 0, 1 ]

    A Map gives O(n) time instead of the O(n²) nested-loop solution.

Review the lessons