JavaScript Interview Questions for Freshers 2026: Core Concepts, the DOM and ES6+

Prepare for JavaScript fresher interviews by reasoning through scope, closures, this, async execution, ES6+ and DOM behaviour. Includes the classic loop-closure trace.

KnowledgeGate Team

Exam prep & CS education

Updated 15 Jul 20265 min read

JavaScript fresher interviews concentrate on a few concepts that trip people up precisely because the language behaves unlike C or Java. Scope, this and asynchronicity decide what the program actually does. A candidate who cannot explain why a short loop prints the wrong number can lose the round quickly.

This guide covers the core language, the DOM and ES6+ features through the questions that expose real understanding. The central worked example traces a closure and scope bug line by line.

What JavaScript fresher interviews test

Interviewers commonly probe closures, scope, hoisting, this, the event loop and modern syntax, then add a small DOM task. They may ask for a definition, but the follow-up is usually an output snippet or a request to change the code safely.

Your job is to reason about scope and execution order aloud. The Placement Preparation category helps you combine this technical work with the wider fresher interview process.

Scope, hoisting and declarations

var is function-scoped. Its declaration is hoisted and the binding is initialised to undefined, so reading it before the declaration line does not throw a reference error, although it rarely expresses the intended logic.

let and const are block-scoped. Their bindings exist from the start of the block but remain in the temporal dead zone until the declaration is evaluated. Access during that interval throws a ReferenceError.

Function declarations are hoisted with their function body, so they can be called earlier in the scope. A variable declaration may be hoisted, but its later assignment is not. A function expression assigned with var therefore behaves differently from a function declaration.

const prevents reassignment of the binding. It does not freeze an object. If const user = { name: "Asha" }, then user.name = "Riya" is allowed, while assigning a different object to user is not. Use Object.freeze() when shallow runtime protection of object properties is actually required.

Worked example: the loop-closure trap

Consider this code:

for (var i = 0; i < 3; i++) {
    setTimeout(function () { console.log(i); }, 0);
}

Trace it in this exact order:

  • var i is ONE function-scoped binding shared by all three callbacks.

  • The synchronous loop finishes (i becomes 3) before any setTimeout callback runs, because those callbacks are queued and executed after the current synchronous code.

  • All three callbacks then read the same i, which is 3.

  • Output: 3, 3, 3.

  • With let i, each iteration gets a fresh block-scoped binding, so the output is 0, 1, 2.

two panels. Left panel "var (shared)": one box i = 3 with three deferred callbacks all arrowing into it, printing 3, 3, 3. Right panel "let (per-iteration)": three separate boxes i = 0, i = 1, i = 2, each with its own callback, printing 0, 1, 2.

The timer delay is not the cause of the shared value. The cause is the one var binding captured by three closures. The timer merely lets the loop finish before those closures read it. Replacing var with let fixes the binding model directly.

this, closures and functions

For a normal function, ask how it was called. In user.show(), this is user. In a plain function call, this is the global object in non-strict browser code and undefined in strict mode. An arrow function does not create its own this; it inherits this from the surrounding lexical scope.

A closure is a function together with access to its outer lexical environment, even after the outer function has returned. A counter shows the useful side of the same mechanism:

function makeCounter() {
    let count = 0;
    return () => ++count;
}
const next = makeCounter();
console.log(next()); // 1
console.log(next()); // 2

The returned function keeps access to its own count, which is private from unrelated code.

call invokes a function immediately with a chosen this and separate arguments. apply does the same with an array-like argument list. bind returns a new function with this, and optionally leading arguments, fixed for a later call.

Async JavaScript and the event loop

Callbacks, promises and async/await express the same broad need at different levels: continue work after an asynchronous operation completes. Promises make success and failure composable. async/await makes promise-based flow read more like sequential code without making it synchronous.

The basic mental model has a call stack for current synchronous work and queues for deferred callbacks. setTimeout(fn, 0) means the callback becomes eligible after the timer threshold; it still waits until the current stack is empty. That is why the loop example completes before any timer callback runs.

Promise reactions use the microtask queue, while timer callbacks use a task queue. After the current synchronous code, queued promise reactions run before the next timer callback. In an output question, trace synchronous statements first, then microtasks, then the next task.

ES6+ and the DOM you should know

Be ready to use these modern language features in small examples:

  • let and const for block-scoped declarations.

  • Arrow functions for concise callbacks and lexical this.

  • Destructuring to extract array positions or object properties.

  • Spread to expand values and rest parameters to collect remaining arguments.

  • Template literals for interpolation and multi-line strings.

  • Default parameters for omitted arguments.

  • export and import for modules.

For the DOM, know how document.querySelector() selects the first matching element and how addEventListener() attaches behaviour without replacing another listener. Events bubble from a target through its ancestors. Event delegation uses one ancestor listener and inspects event.target, which is useful for dynamic lists.

Prefer === when you do not explicitly want type coercion. With ==, values such as 0 and "0" can compare equal after conversion. Also know the common falsy values, including false, 0, "", null, undefined and NaN. The Web technologies for teaching exams guide gives the surrounding HTML, HTTP and browser context.

Short version and next step

Scope decides what a closure captures, the call site decides this for normal functions, and the event loop decides when deferred work runs. Know those three ideas cold, then add modern syntax and basic DOM event handling.

Work through the Complete JavaScript course, revisit Technical interview prep for core CS subjects, and rehearse mixed questions under time with the Mera Placement Hoga Anushasan bundle. Do not stop at predicting output. Explain which binding, call site or queue produces it.