codejump

Interview questionsJavaScript

JavaScript interview questions and answers

30 JavaScript questions picked from Codejump's quizzes, from the basics a junior is expected to know to the details that trip up senior candidates. Each one comes with its answer and an explanation — try to answer before you open it.

Junior level JavaScript questions

  1. 1.A Promise can be in three possible states. Which answer lists them correctly?

    javascript
    const p1 = new Promise((resolve) => resolve(42));
    // p1 is fulfilled with value 42
    
    const p2 = new Promise((_, reject) => reject(new Error("oops")));
    // p2 is rejected with an Error
    
    const p3 = new Promise(() => {}); // never resolves
    // p3 stays pending forever
    • A.loading, success, failure
    • B.idle, running, done
    • C.waiting, resolved, errored
    • D.pending, fulfilled, rejected
    Show answer

    Answer: D. pending, fulfilled, rejected

    A Promise always exists in one of three states: | State | Meaning | |---|---| | pending | Initial state — the operation has not completed yet | | fulfilled | The operation completed successfully — has a result value | | rejected | The operation failed — has a reason (error) | Once a Promise transitions from pending to either fulfilled or rejected, it is settled and cannot change state again.

    From the quiz Promises & Callbacks

  2. 2.What is the correct way to remove an HTML element from the DOM?

    javascript
    const oldElement = document.getElementById("old");
    oldElement.remove(); // Element is removed from the DOM
    • A.element.delete();
    • B.element.remove();
    • C.document.removeChild(element);
    • D.element.innerHTML = "";
    Show answer

    Answer: B. element.remove();

    element.remove() is the modern, straightforward way to remove an element from the DOM.

    From the quiz DOM & Events

  3. 3.What is the main purpose of using higher-order functions?

    javascript
    // Without higher-order functions (repetitive)
    const doubled = [];
    for (let i = 0; i < numbers.length; i++) {
      doubled.push(numbers[i] * 2);
    }
    
    const squared = [];
    for (let i = 0; i < numbers.length; i++) {
      squared.push(numbers[i] * numbers[i]);
    }
    
    // With higher-order functions (reusable)
    const map = (arr, fn) => arr.map(fn);
    const doubled = map(numbers, x => x * 2);
    const squared = map(numbers, x => x * x);
    • A.To simplify code and reduce redundancy.
    • B.To make functions reusable and more modular.
    • C.To allow functions to operate on other functions.
    • D.All of the above.
    Show answer

    Answer: D. All of the above.

    Higher-order functions provide several benefits: 1. Code reusability: Write once, use in multiple contexts 2. Modularity: Separate concerns and make code more organized 3. Abstraction: Hide implementation details and focus on what not how Example:

    From the quiz Pure Functions & Immutability

  4. 4.Which of the following is not a primitive data type in JavaScript?

    • A.Number
    • B.String
    • C.Object
    • D.Boolean
    Show answer

    Answer: C. Object

    Primitive types in JavaScript include:
    • string
    • number
    • boolean
    • null
    • undefined
    • symbol
    • bigint Object is not a primitive. It is a reference type.

    From the quiz Core Concepts

  5. 5.What is the output?

    javascript
    console.log(null == undefined);
    console.log(null === undefined);
    • A.false then false
    • B.true then true
    • C.true then false
    • D.false then true
    Show answer

    Answer: C. true then false

    With == (loose equality), null and undefined are only equal to each other — not to 0, "", or false. This is a special rule in the ECMAScript spec. With === (strict equality), no type coercion occurs. null and undefined are different types, so the result is false.

    From the quiz Output Basics

  6. 6.Which of the following correctly defines a method inside a class?

    javascript
    class Example {
      methodName() {
        console.log("Hello");
      }
    }
    • A.methodName: function() {...}
    • B.methodName() {...}
    • C.this.methodName = function() {...}
    • D.def methodName() {...}
    Show answer

    Answer: B. methodName() {...}

    Inside a class body, methods are defined using the shorthand syntax: No function keyword, no colon, no this assignment needed.

    From the quiz Classes & Objects

  7. 7.What is CORS (Cross-Origin Resource Sharing)?

    javascript
    // Frontend running on https://example.com
    fetch("https://api.other.com/data")
      .then(response => response.json())
      .catch(error => console.log("CORS Error"));
      // Browser blocks this because it's a different domain!
    • A.A method to hide JavaScript code from users.
    • B.A way to compress JavaScript files.
    • C.A browser security policy that controls how resources can be shared between different domains.
    • D.A technique for caching API responses.
    Show answer

    Answer: C. A browser security policy that controls how resources can be shared between different domains.

    CORS is a browser security mechanism that controls which origins (domains) can access resources from a server. Example of CORS issue: Fixing CORS (server-side): Types of CORS requests: 1. Simple requests (no preflight check needed):
    • GET, HEAD, POST only
    • Standard headers only 2. Preflight requests (browser sends OPTIONS first):
    • Custom headers or methods (PUT, DELETE)
    • Browser asks permission before sending actual request

    From the quiz Common Vulnerabilities

  8. 8.What is debugging in programming?

    javascript
    function calculateTotal(items) {
      console.log("Items:", items); // Debug: check input
      
      let total = 0;
      for (let item of items) {
        console.log("Adding:", item.price); // Debug: check each iteration
        total += item.price;
      }
      
      console.log("Total:", total); // Debug: check result
      return total;
    }
    • A.Writing more code to add features.
    • B.Removing test code.
    • C.Testing new features.
    • D.The process of finding and fixing bugs/errors in code.
    Show answer

    Answer: D. The process of finding and fixing bugs/errors in code.

    Debugging is the process of identifying and fixing errors (bugs) in code. It's an essential part of development. Debugging tools:
    • Browser DevTools (Chrome, Firefox)
    • Console logging
    • Debugger statements
    • IDE debuggers Example of debugging with console: Example of debugging with debugger:

    From the quiz Unit Testing

  9. 9.What will this code log?

    javascript
    Promise.resolve(10)
      .then(val => val * 2)
      .then(val => console.log(val));
    • A.20
    • B.10
    • C.undefined
    • D.An error is thrown
    Show answer

    Answer: A. 20

    .then() returns a new Promise that resolves with the return value of the callback. This enables chaining: 1. Promise.resolve(10) → Promise fulfilled with 10 2. .then(val => val * 2) → 10 * 2 = 20 → new Promise fulfilled with 20 3. .then(val => console.log(val)) → logs 20

    From the quiz Promises & Callbacks

  10. 10.What will happen if you use document.querySelector(".my-class")?

    javascript
    const firstButton = document.querySelector("button"); // First button on the page
    const firstActive = document.querySelector(".active"); // First element with class "active"
    • A.It selects all elements with the class my-class.
    • B.It selects the first element with the class my-class.
    • C.It returns an array of elements.
    • D.It throws an error if no element is found.
    Show answer

    Answer: B. It selects the first element with the class my-class.

    querySelector returns the first element that matches the selector. To select all matching elements, use querySelectorAll: Return values:
    • querySelector → Single element or null
    • querySelectorAll → NodeList (array-like) of elements

    From the quiz DOM & Events

Mid level JavaScript questions

  1. 11.What does the async keyword do when added to a function?

    javascript
    async function greet() {
      return "Hello";
    }
    
    greet().then(console.log); // "Hello"
    • A.Runs the function synchronously
    • B.Makes the function return a Promise
    • C.Stops JavaScript execution until the function completes
    • D.Converts a function into a generator
    Show answer

    Answer: B. Makes the function return a Promise

    An async function always returns a Promise, regardless of what it actually returns inside.
    • If it returns a value, that value is wrapped in Promise.resolve(value)
    • If it throws an error, the Promise is rejected with that error Example:

    From the quiz Async/Await

  2. 12.What will happen when this code is executed and a list item is clicked?

    javascript
    document.getElementById("list").addEventListener("click", function(event) {
      if (event.target.tagName === "LI") {
        console.log("List item clicked: " + event.target.textContent);
      }
    });
    • A.Error: event.target is undefined
    • B.The click event is not captured
    • C.The event propagation is stopped
    • D."List item clicked: [text of clicked item]" is logged
    Show answer

    Answer: D. "List item clicked: [text of clicked item]" is logged

    The listener checks if the clicked element (event.target) is an LI tag. If so, it logs the text content. Step by step: 1. User clicks a list item 2. Event bubbles up to the #list container 3. The listener checks: is event.target an LI? Yes 4. Logs the item's text

    From the quiz Browser APIs & Storage

  3. 13.What is the output of the following code?

    javascript
    function multiply(a) {
      return function(b) {
        return a * b;
      };
    }
    
    const multiplyByTwo = multiply(2);
    console.log(multiplyByTwo(5));
    • A.7
    • B.5
    • C.10
    • D.2
    Show answer

    Answer: C. 10

    Step by step: 1. multiply(2) returns a function: function(b) { return 2 * b; } 2. This returned function is stored in multiplyByTwo 3. multiplyByTwo(5) calls the returned function with b = 5 4. The function evaluates: 2 * 5 = 10 This is an example of partial application — we pre-fill the first argument (2) to create a specialized function.

    From the quiz Higher-Order Functions

  4. 14.What is the value of y after execution?

    javascript
    var y = 1;
    
    function test() {
      y = 2;
      var y;
    }
    
    test();
    console.log(y);
    • A.1
    • B.2
    • C.undefined
    • D.ReferenceError
    Show answer

    Answer: A. 1

    Inside test, the local declaration var y is hoisted to the top of the function. So the function behaves like this: That means the assignment y = 2 modifies the local y, not the global one. So the global y remains 1.

    From the quiz Functions & Scope

  5. 15.What is the output?

    javascript
    console.log("1");
    
    setTimeout(() => console.log("2"), 0);
    
    Promise.resolve().then(() => console.log("3"));
    
    console.log("4");
    • A.1 2 3 4
    • B.1 4 3 2
    • C.1 4 2 3
    • D.1 3 4 2
    Show answer

    Answer: B. 1 4 3 2

    The JavaScript event loop processes tasks in this order: 1. Synchronous code runs first: "1" and "4". 2. Microtask queue (Promises) runs before the next macrotask: "3". 3. Macrotask queue (setTimeout): "2".

    From the quiz Tricky Outputs

  6. 16.What will this code log?

    javascript
    class Person {
      constructor(name) {
        this._name = name;
      }
    
      get name() {
        return this._name.toUpperCase();
      }
    
      set name(value) {
        this._name = value.toLowerCase();
      }
    }
    
    const user = new Person("Alice");
    user.name = "BOB";
    console.log(user.name);
    • A."Alice"
    • B."BOB"
    • C."BOB"
    • D."BOB".toUpperCase()
    Show answer

    Answer: C. "BOB"

    Step by step: 1. new Person("Alice") → this._name = "Alice" 2. user.name = "BOB" → triggers the setter → this._name = "BOB".toLowerCase() → this._name = "bob" 3. console.log(user.name) → triggers the getter → return this._name.toUpperCase() → "BOB" So the final output is "BOB".

    From the quiz Inheritance & Prototypes

  7. 17.What HTTP request is sent before a complex CORS request?

    javascript
    fetch("https://api.example.com/data", {
      method: "PUT", // Not a simple method
      headers: {
        "Content-Type": "application/json",
        "X-Custom-Header": "value" // Custom header
      },
      body: JSON.stringify({ data: "..." })
    });
    • A.GET request to check if CORS is enabled.
    • B.OPTIONS request to ask permission before the actual request.
    • C.HEAD request to retrieve headers only.
    • D.POST request to establish connection.
    Show answer

    Answer: B. OPTIONS request to ask permission before the actual request.

    For complex requests (custom headers, PUT/DELETE methods, etc.), the browser first sends an OPTIONS preflight request to ask the server if it allows the actual request. Example of a complex request that triggers preflight: Preflight request sent by browser: Server response (permitting the request): Browser then sends actual request: Why preflight happens:
    • Protects old servers that don't understand CORS
    • Prevents unintended state changes from cross-origin requests

    From the quiz Secure Coding Practices

  8. 18.What is a spy in testing?

    javascript
    const user = {
      greet(name) {
        return `Hello, ${name}!`;
      }
    };
    
    // Spy on the method
    const spy = jest.spyOn(user, "greet");
    
    // Call the method
    const result = user.greet("Alice");
    
    // Verify the spy tracked the call
    expect(spy).toHaveBeenCalled();
    expect(spy).toHaveBeenCalledWith("Alice");
    expect(spy).toHaveBeenCalledTimes(1);
    expect(result).toBe("Hello, Alice!"); // Original functionality works
    • A.A hidden observer in tests.
    • B.A security feature.
    • C.A function wrapper that tracks calls without replacing functionality.
    • D.A mocking library.
    Show answer

    Answer: C. A function wrapper that tracks calls without replacing functionality.

    A spy wraps a function to track how it's called while keeping the original functionality. Example: Difference from mock: Use cases:
    • Verify a method was called
    • Track call arguments
    • Verify call frequency
    • Keep original functionality for integration testing Cleanup spies:

    From the quiz Mocks, Spies & Integration

  9. 19.What does the await keyword do inside an async function?

    javascript
    async function fetchData() {
      const result = await Promise.resolve("Data ready");
      console.log(result); // "Data ready"
    }
    
    fetchData();
    console.log("This runs before the await resolves");
    • A.Delays the execution of an entire script
    • B.Converts a callback function into a synchronous function
    • C.Automatically catches errors in asynchronous functions
    • D.Waits for a Promise to resolve before continuing execution inside the function
    Show answer

    Answer: D. Waits for a Promise to resolve before continuing execution inside the function

    await pauses the execution of the async function at that line until the Promise resolves or rejects. While waiting, the rest of the JavaScript program continues running normally. Example: Output:

    From the quiz Async/Await

  10. 20.What is the main benefit of lazy loading images?

    javascript
    <img src="image.jpg" loading="lazy" alt="Description">
    • A.It loads all images at once to improve performance.
    • B.It increases image quality dynamically.
    • C.It delays image loading until they are needed, reducing initial page load time.
    • D.It prevents images from being cached in the browser.
    Show answer

    Answer: C. It delays image loading until they are needed, reducing initial page load time.

    Lazy loading defers image loading until the user scrolls them into view. This reduces:
    • Initial page load time
    • Bandwidth usage
    • Memory consumption Using native lazy loading (HTML attribute): Using Intersection Observer API (advanced): HTML:

    From the quiz Browser APIs & Storage

Senior level JavaScript questions

  1. 21.What happens in the following scenario when the setTimeout callback executes inside a Promise resolution chain?

    javascript
    Promise.resolve().then(() => {
      console.log('Promise resolved');
      setTimeout(() => {
        console.log('Timeout inside Promise');
      }, 0);
    });
    • A.The setTimeout callback is executed before the Promise.resolve callback
    • B.The setTimeout callback is executed immediately after the Promise resolution
    • C.The setTimeout callback is executed as part of the Promise resolution, before the .then block completes
    • D.The setTimeout callback will execute immediately after the current stack is empty
    Show answer

    Answer: D. The setTimeout callback will execute immediately after the current stack is empty

    When setTimeout is called inside a Promise handler (a microtask): 1. The Promise handler runs → logs "Promise resolved" 2. setTimeout is scheduled in the macrotask queue 3. The Promise handler completes 4. JavaScript checks the microtask queue (empty) 5. Then processes the next macrotask: the setTimeout callback 6. Logs "Timeout inside Promise" The key insight: A microtask that schedules a macrotask creates a new macrotask, which runs only after all microtasks and the current macrotask complete.

    From the quiz Concurrency & Workers

  2. 22.What is a key advantage of using event delegation for dynamically added elements?

    javascript
    function addItem(text) {
      const li = document.createElement("li");
      li.textContent = text;
      
      // Must add listener to each new item
      li.addEventListener("click", () => {
        console.log("Clicked: " + text);
      });
      
      document.getElementById("list").appendChild(li);
    }
    
    // Each call adds another listener — memory leak risk
    addItem("Item 1");
    addItem("Item 2");
    addItem("Item 3");
    • A.It automatically adds listeners to new elements.
    • B.It prevents event bubbling entirely.
    • C.It provides better performance than adding individual listeners.
    • D.It makes the code run synchronously.
    Show answer

    Answer: C. It provides better performance than adding individual listeners.

    Event delegation is superior for performance with dynamic content: Without delegation (inefficient): With delegation (efficient): Benefits:
    • One listener for many elements
    • New elements automatically handled
    • Lower memory usage
    • Easier to maintain

    From the quiz Performance & Rendering

  3. 23.What will the following code output?

    javascript
    let count = 0;
    
    function increment() {
      count++;
    }
    
    increment();
    increment();
    console.log(count);
    • A.0
    • B.2
    • C.undefined
    • D.NaN
    Show answer

    Answer: B. 2

    The function increment is impure because it modifies the global variable count. Step by step: 1. increment() first time → count becomes 1 2. increment() second time → count becomes 2 3. console.log(count) → logs 2 This is an example of a side effect — the function modifies external state.

    From the quiz Composition & Monads

  4. 24.What will be the output of the following code?

    javascript
    console.log(+"10" + 5);
    • A.15
    • B."105"
    • C."10"5
    • D.NaN
    Show answer

    Answer: A. 15

    The unary + converts the string "10" into the number 10. So the expression becomes: which results in 15.

    From the quiz Advanced Patterns

  5. 25.What is the output?

    javascript
    function tag(strings, ...values) {
      console.log(strings);
      console.log(values);
    }
    
    const name = "World";
    const num = 42;
    tag`Hello ${name}, you have ${num} messages`;
    • A.["Hello ", ", you have ", " messages"] then ["World", 42]
    • B."Hello World, you have 42 messages" then []
    • C.["Hello World, you have 42 messages"] then ["World", 42]
    • D.["Hello ", " messages"] then ["World", 42]
    Show answer

    Answer: A. ["Hello ", ", you have ", " messages"] then ["World", 42]

    A tagged template literal calls the tag function with:
    • strings: an array of the static string parts split at each interpolation.
    • ...values: the evaluated interpolated expressions. For ` tagHello ${name}, you have ${num} messages `:
    • strings = ["Hello ", ", you have ", " messages"] (3 parts around 2 interpolations)
    • values = ["World", 42] Note: strings.length is always values.length + 1.

    From the quiz Advanced Output Traps

  6. 26.What will the following code output?

    javascript
    const id = Symbol('id');
    const user = {
      name: 'Bob',
      [id]: 123
    };
    
    console.log(Object.keys(user).length);
    console.log(user[id]);
    • A.2 and 123
    • B.1 and undefined
    • C.1 and 123
    • D.2 and undefined
    Show answer

    Answer: C. 1 and 123

    Object.keys() only returns enumerable string-keyed own properties. Symbol-keyed properties are excluded. So Object.keys(user) returns ['name'] → length 1. Accessing user[id] with the exact Symbol reference returns 123.

    From the quiz Advanced OOP

  7. 27.What vulnerability exists in this code?

    javascript
    function merge(target, source) {
      for (let key in source) {
        target[key] = source[key]; // Vulnerable!
      }
      return target;
    }
    
    // Usage
    const user = {};
    const userInput = JSON.parse(req.body);
    merge(user, userInput);
    • A.No vulnerability.
    • B.SQL injection vulnerability.
    • C.XSS vulnerability.
    • D.Prototype pollution vulnerability.
    Show answer

    Answer: D. Prototype pollution vulnerability.

    Prototype pollution allows attackers to modify Object.prototype, affecting all objects in the application. The attack: Impact: Secure approach:

    From the quiz XSS, CSRF & Injection

  8. 28.What is the challenge in debugging async code?

    javascript
    async function loadUser() {
      const user = await fetch("/api/user"); // Stack trace shows fetch here
      console.log(user); // Error occurs here, but trace doesn't show the connection
    }
    • A.Async code executes immediately.
    • B.Async code cannot be debugged.
    • C.The call stack is lost when async operations complete.
    • D.Async code is always synchronous.
    Show answer

    Answer: C. The call stack is lost when async operations complete.

    When debugging async code, the call stack shows where the async operation started, not where the result is processed. Example of confusing stack trace: Debugging async challenges: 1. Call stack doesn't show original caller 2. Hard to trace through multiple async operations 3. Errors in Promises can be silent Solutions: 1. Use async/await instead of .then() (better stack traces): 2. Use DevTools with async call stacks enabled:
    • In DevTools → Sources → Check Async
    • Shows full async chain 3. Add meaningful debugging:

    From the quiz E2E & Performance Testing

  9. 29.Which of the following statements about the JavaScript Event Loop is true in terms of priority between different types of tasks?

    javascript
    setTimeout(() => console.log('setTimeout'), 0);
    Promise.resolve().then(() => console.log('Promise'));
    // Output: Promise, setTimeout
    • A.Macrotasks such as setTimeout always execute before any microtasks, regardless of when they were scheduled.
    • B.Both microtasks and macrotasks have equal priority, and the Event Loop handles them based on the order they were scheduled.
    • C.Microtasks, such as Promise callbacks, always run before any other macrotasks, like setTimeout, even if they are scheduled later.
    • D.Macrotasks always run in sequence with a delay of at least 1 ms between them, while microtasks run sequentially without delay.
    Show answer

    Answer: C. Microtasks, such as Promise callbacks, always run before any other macrotasks, like setTimeout, even if they are scheduled later.

    The Event Loop enforces this strict priority: 1. Synchronous code (call stack) — highest priority 2. All microtasks (Promise callbacks, queueMicrotask, MutationObserver) 3. One macrotask (setTimeout, setInterval, I/O, UI rendering) 4. Go back to step 2 All microtasks complete before any single macrotask runs. This is a hard rule that cannot be violated, even if a macrotask was scheduled earlier. Example: Even though setTimeout was called first, the Promise runs first.

    From the quiz Concurrency & Workers

  10. 30.Why is requestAnimationFrame() preferred over setTimeout() for animations?

    javascript
    function animate() {
      element.style.left = element.offsetLeft + 1 + "px";
      setTimeout(animate, 1000/60); // Tries to hit 60fps manually
    }
    • A.It executes faster than setTimeout().
    • B.It doesn't create callbacks.
    • C.It synchronizes with the browser's refresh rate, avoiding jank.
    • D.It runs on a separate thread.
    Show answer

    Answer: C. It synchronizes with the browser's refresh rate, avoiding jank.

    requestAnimationFrame (rAF) syncs with the browser's refresh cycle (typically 60fps = 16.67ms). Using setTimeout (inefficient): Problem: The actual frame rate might not align, causing jank (stuttering). Using requestAnimationFrame (efficient): Key advantages:
    • Synchronization: Runs before each repaint (optimal timing)
    • Smooth animation: No jank due to timing misalignment
    • Battery efficient: Pauses when tab is hidden
    • Automatic throttling: Browser controls frequency

    From the quiz Performance & Rendering

Practise 900+ more JavaScript questions

Timed quizzes with instant feedback, the questions you miss coming back until they stick, coding challenges and AI mock interviews — free to start.