JavaScript Basics • Modern Syntax • DOM and Browser • Coding Tasks • College Projects • 2026

JavaScript Interview Questions for Freshers

JavaScript interviews for freshers check that you can explain the basics in your own words, write a small function on a whiteboard and talk honestly about what you built. Expect questions on data types and typeof, null and undefined, NaN and decimal maths, modern syntax like spread and optional chaining, fetch and the DOM, a few short coding tasks and your college projects. It is written for final-year students, new graduates and anyone heading into a first JavaScript job from an internship or a bootcamp. Read each sample answer, then say your own version out loud. Closures, this, the event loop and promises in depth are on the main JavaScript page.

Search all questions by round, difficulty and level, or save the ones you want to practice.

Data Types 4 questions

Easy Technical round Fresher Practice question

1. What data types does JavaScript have, and what does typeof give you for null, an array and a function?

What the interviewer is really testing:
Whether you know the basic building blocks and the famous typeof quirks that trip up beginners in real code.
Answer frame:

Primitives: string, number, bigint, boolean, undefined, symbol and null; single values that can't be changed in place.

Objects: everything else, including arrays, functions and dates.

Quirks: typeof null is "object", an array is also "object", a function is "function".

Safe checks: Array.isArray for arrays and === null for null.

Sample spoken answer:

“JavaScript has seven primitive types: string, number, bigint, boolean, undefined, symbol and null. Primitives are single values that can't be changed in place, so any string method gives me a new string. Everything else is an object, and that includes arrays, functions and dates. The typeof operator has a few surprises. typeof null returns object, which is an old bug the language kept so it wouldn't break existing sites. An array also comes back as object, so to check for an array I use Array.isArray. A function is the one object that gets its own answer, function. So when I need to tell these apart, I check null with triple equals first, then use Array.isArray, and only then fall back to typeof.”

Code:
typeof "hi"            // "string"
typeof 42              // "number"
typeof undefined       // "undefined"
typeof null            // "object"
typeof [1, 2]          // "object"
typeof function () {}  // "function"
Array.isArray([1, 2])  // true
Red flag to avoid:

Saying arrays are their own type in typeof, or not knowing that typeof null returns object.

They may ask next:
  • What does typeof return for a variable that was never declared, and does it throw?
  • How is bigint different from number, and when would you need it?
Say it in 60 seconds
Easy Technical round Fresher Practice question

2. What's the difference between undefined, null and a 'not defined' error?

What the interviewer is really testing:
Whether you can tell the two empty values apart and read one of the most common beginner error messages.
Answer frame:
undefined vs null vs not defined
undefinedthe default when a variable has no value yet, a property is missing or a function returns nothing.
nullan empty value a programmer sets on purpose.
not defineda ReferenceError, because the name was never declared at all.
Sample spoken answer:

“undefined is what JavaScript gives me by default. If I declare a variable and don't assign it, read a property that doesn't exist, or call a function that has no return, I get undefined. null is different because I set it myself, on purpose, to say there's no value here, like clearing the selected item in a list. Not defined isn't a value at all, it's a ReferenceError. It means I used a name that was never declared, and it's often just a typo. For comparisons, null double-equals undefined is true, but with triple equals it's false. So when I want to check for both at once, I either write value == null with a short comment, or use the nullish operator.”

Code:
let a;
console.log(a);          // undefined
const user = { name: "Lee" };
console.log(user.age);   // undefined
let picked = null;       // cleared on purpose
console.log(score);      // ReferenceError: score is not defined
Red flag to avoid:

Treating null and undefined as the same thing, or calling a ReferenceError an undefined value.

They may ask next:
  • What does a function return if it has no return statement?
  • Why might an API send null for a field instead of leaving the field out?
Say it in 60 seconds
Easy Technical round Fresher Practice question

3. Which values are falsy in JavaScript? Would an empty array or the string '0' pass an if check?

What the interviewer is really testing:
Whether you know exactly which values an if statement treats as false, because wrong guesses cause quiet bugs with zero and empty strings.
Answer frame:

Falsy list: false, 0, -0, 0n, the empty string, null, undefined and NaN.

Everything else is truthy: including [], {}, "0" and "false".

Trap: if (count) skips a real count of zero, so check exactly what you mean.

Sample spoken answer:

“There's a short list of falsy values: false, zero, negative zero, the bigint zero, the empty string, null, undefined and NaN. Everything else is truthy. So an empty array passes an if check, and so does an empty object, and so do the strings zero and false, because they're non-empty strings. Where this bites people is a check like if (count) when zero is a valid count, or if (name) when an empty string should be allowed. In those cases I check exactly what I mean, like count !== undefined, or items.length > 0 when I want to know if an array has anything in it. To turn a value into a real boolean I use Boolean(value), which reads more clearly to most teammates than a double exclamation mark.”

Red flag to avoid:

Saying an empty array or an empty object is falsy.

They may ask next:
  • How would you check that an object has no keys at all?
  • What does !!value do, and why do people write it?
Say it in 60 seconds
Medium Technical round Fresher Practice question

4. What do JSON.stringify and JSON.parse do? What happens to a Date, a function or an undefined field when you stringify an object?

What the interviewer is really testing:
Whether you can move data to a server or into storage and back without losing pieces or crashing on bad input.
Answer frame:

stringify: turns a value into a JSON string for sending or storing.

parse: turns a JSON string back into values, and throws on bad input.

Losses: functions and undefined fields are left out, a Date becomes an ISO string, NaN becomes null.

Sample spoken answer:

“JSON.stringify turns a JavaScript value into a JSON string, which is what I send in a request body or save in localStorage. JSON.parse does the reverse. JSON only knows strings, numbers, booleans, null, arrays and plain objects, so some things don't survive. Functions and properties set to undefined are simply left out of objects. A Date becomes an ISO string, and after parse it stays a string, not a Date, so I have to convert it back myself. NaN and Infinity become null. On the parse side, JSON is stricter than JavaScript: keys need double quotes and trailing commas aren't allowed, and bad input throws a SyntaxError. So when I parse anything from outside, like a stored value or a server reply, I wrap it in try and catch.”

Code:
const data = { name: "Lee", joined: new Date(0), greet() {}, nick: undefined, score: NaN };
JSON.stringify(data);
// '{"name":"Lee","joined":"1970-01-01T00:00:00.000Z","score":null}'

JSON.parse('{"a": 1}');  // { a: 1 }
JSON.parse("{'a': 1}");  // SyntaxError: single quotes aren't JSON
Red flag to avoid:

Expecting a Date to come back as a Date after parse, or parsing outside data with no error handling.

They may ask next:
  • What do the second and third arguments of JSON.stringify do?
  • What happens if you stringify an object that refers to itself?
Say it in 60 seconds

Numbers 2 questions

Medium Technical round Fresher Practice question

5. What is NaN? Why is NaN === NaN false, and how do you check for it properly?

What the interviewer is really testing:
Whether you can catch bad numeric input correctly instead of writing a check that can never be true.
Answer frame:

What it is: a number value meaning a calculation had no valid numeric result, like 'abc' * 2.

Never equal: NaN isn't equal to anything, itself included.

Right check: Number.isNaN(x); the older global isNaN converts first, so isNaN('hello') is true.

Sample spoken answer:

“NaN stands for not a number, but funnily enough typeof NaN is number. It's what I get when a calculation can't produce a real number, like multiplying a word by two, or calling Number on text such as twelve px. The rule is that NaN isn't equal to anything, not even itself, so a triple-equals check never finds it. The proper check is Number.isNaN. There's also an older global isNaN, but it converts the value to a number first, so isNaN('hello') returns true even though that's a string, not NaN. In a form, I'd convert the input with Number, then use Number.isNaN to show an error before the bad value spreads into a total and turns everything it touches into NaN.”

Code:
Number("12px")         // NaN
parseInt("12px")       // 12
NaN === NaN            // false
Number.isNaN(NaN)      // true
isNaN("hello")         // true, it converts first
Number.isNaN("hello")  // false
Object.is(NaN, NaN)    // true
Red flag to avoid:

Checking with x === NaN, or trusting the global isNaN on strings.

They may ask next:
  • What's the difference between Number('12px') and parseInt('12px')?
  • Does [NaN].includes(NaN) find it? What about [NaN].indexOf(NaN)?
Say it in 60 seconds
Medium Technical round Fresher Practice question

6. Why does 0.1 + 0.2 not equal 0.3 in JavaScript, and how would you handle it?

What the interviewer is really testing:
Whether you understand how numbers are stored and can compare or display decimals without surprising bugs.
Answer frame:

Cause: every number is a 64-bit binary floating point value, and 0.1 has no exact binary form.

Result: the sum comes out as 0.30000000000000004.

Compare: check that the difference is below a small tolerance.

Display or store: round with toFixed for display, or do the maths in whole units like cents.

Sample spoken answer:

“All numbers in JavaScript are 64-bit floating point, stored in binary. Just like one third can't be written exactly in decimal, 0.1 and 0.2 can't be written exactly in binary, so each is stored as the closest value, and the tiny errors add up. The sum comes out as 0.30000000000000004, so a triple-equals check fails. It isn't a JavaScript bug; other languages using the same number format do exactly the same. To compare, I check that the difference is smaller than a small tolerance, like Number.EPSILON for values around one. For showing a result I round with toFixed, keeping in mind it returns a string. And for prices, I'd do the maths in whole cents as integers, so nothing needs rounding until I display it.”

Code:
0.1 + 0.2                                   // 0.30000000000000004
0.1 + 0.2 === 0.3                           // false
Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON  // true
(0.1 + 0.2).toFixed(2)                      // "0.30", a string
const totalCents = 10 + 20;                 // 30, exact
Red flag to avoid:

Calling it a JavaScript bug, or rounding with toFixed and then comparing the strings.

They may ask next:
  • What is the largest whole number JavaScript can store exactly in a normal number?
  • Why does toFixed return a string, and what trouble can that cause?
Say it in 60 seconds

Functions 2 questions

Medium Technical round Fresher Practice question

7. If I pass an object into a function and change it there, does the caller see the change? What about a number?

What the interviewer is really testing:
Whether you understand how values and references move into functions, which explains a whole family of 'why did my data change' bugs.
Answer frame:

Primitives: the function gets a copy of the value, so changes stay inside.

Objects: the function gets a copy of the reference, so both point at the same object.

Mutate vs reassign: changing a property shows outside; pointing the parameter at a new object doesn't.

Sample spoken answer:

“With a number or a string, the function gets its own copy of the value, so whatever I do inside stays inside. With an object or an array it's more subtle. The variable holds a reference, and the function gets a copy of that reference. So the caller and the function both point at the same object. If I change a property, or push into the array, the caller sees it. But if I reassign the parameter to a brand new object, that only changes the function's local name, and the caller still has the original. That's why people call it pass by sharing. In practice I try not to surprise callers: if a function needs a changed version, I return a new object built with spread instead of editing the one passed in.”

Code:
function update(n, user) {
  n = n + 1;               // local copy only
  user.name = "Kim";       // same object as the caller's
  user = { name: "New" };  // local name now points elsewhere
}
let count = 1;
const person = { name: "Lee" };
update(count, person);
console.log(count, person.name); // 1 "Kim"
Red flag to avoid:

Saying objects are passed by reference so reassigning the parameter changes the caller's variable.

They may ask next:
  • How would you write that function so it never changes the caller's object?
  • Does const stop you from changing an object's properties?
Say it in 60 seconds
Easy Technical round Fresher Practice question

8. What is a callback function? Give me one example that runs right away and one that runs later.

What the interviewer is really testing:
Whether you understand functions as values, and that a callback is not automatically asynchronous.
Answer frame:

Definition: a function you pass to another function, which calls it for you.

Right away: a sort comparator runs during the sort call itself.

Later: setTimeout or addEventListener call it after the current code finishes.

Why promises came: nested async callbacks get hard to read and to handle errors in.

Sample spoken answer:

“A callback is just a function I hand to another function so it can call it for me. Functions are values in JavaScript, so I can pass them around like anything else. Some callbacks run right away. When I call sort with a comparator like (a, b) => a - b, sort calls it many times before it returns. That comparator matters, because sort without one compares items as strings, so ten comes before two. Other callbacks run later. With setTimeout or a click listener, my function is stored and called after the current code finishes, when the timer fires or the user clicks. When several async steps depend on each other, those callbacks nest deeper and deeper, and handling errors gets messy. That's the problem promises and async/await were built to fix.”

Code:
const nums = [10, 2, 33];
nums.sort();                 // [10, 2, 33], compared as strings
nums.sort((a, b) => a - b);  // [2, 10, 33], callback runs during sort

console.log("first");
setTimeout(() => console.log("third"), 1000); // runs later
console.log("second");
Red flag to avoid:

Saying every callback is asynchronous, or not being able to name a callback you've written.

They may ask next:
  • What is callback hell, and how would you flatten it?
  • Why does sort without a comparator put 10 before 2?
Say it in 60 seconds

Syntax Basics 4 questions

Easy Technical round Fresher Practice question

9. What do the three dots mean in JavaScript? Show me spread, rest and destructuring with a default value.

What the interviewer is really testing:
Whether you are comfortable with modern syntax that appears in almost every codebase and every code sample you'll read.
Answer frame:

Spread: expands an array or object into single items, in calls, array literals and object literals.

Rest: collects the leftover items into an array or object, in parameters and destructuring.

Destructuring: pulls values out by position or by name; a default kicks in only for undefined.

Sample spoken answer:

“The same three dots do two opposite jobs depending on where they sit. Spread expands things: Math.max(...nums) passes each number as its own argument, and { ...user, role: 'admin' } copies an object and overrides one field. Rest collects things: in a function's parameters, ...rest gathers every extra argument into a real array, and in destructuring it gathers whatever I didn't name. Destructuring itself is a short way to pull values out, by position for arrays and by name for objects. I can give a default, like pages = 100, but it only applies when the value is undefined, not when it's null. A neat trick it enables is swapping two variables in one line without a temporary variable.”

Code:
const nums = [4, 9, 2];
Math.max(...nums);                          // 9, spread into arguments
const user = { name: "Lee", role: "viewer" };
const admin = { ...user, role: "admin" };   // copy, then override

function sum(first, ...rest) {              // rest collects extras
  return rest.reduce((a, b) => a + b, first);
}
const { title, pages = 100 } = { title: "Notes" }; // pages is 100
const [head, ...tail] = [1, 2, 3];          // head 1, tail [2, 3]
let a = 1, b = 2;
[a, b] = [b, a];                            // swap
Red flag to avoid:

Mixing up spread and rest, or expecting a default value to replace null.

They may ask next:
  • What happens if you try to destructure a property from undefined?
  • Why must the rest parameter be the last one in the list?
Say it in 60 seconds
Medium Technical round Fresher Practice question

10. What do ?. and ?? do, and why is volume ?? 10 often safer than volume || 10?

What the interviewer is really testing:
Whether you can read nested data without crashes and pick defaults that don't wipe out valid values like zero.
Answer frame:

Optional chaining: a?.b gives undefined if a is null or undefined, instead of throwing.

Nullish coalescing: x ?? y falls back only when x is null or undefined.

Versus ||: || falls back on any falsy value, so it replaces a real 0 or an empty string.

Sample spoken answer:

“Optional chaining, the question mark dot, lets me read deep into an object without crashing. user?.address?.city gives me undefined if user or address is missing, instead of throwing 'cannot read properties of undefined'. It works for calls too, like onDone?.(). The double question mark is nullish coalescing: it uses the right side only when the left side is null or undefined. That's the difference from the OR operator, which falls back on any falsy value. So if a user sets the volume to zero, volume || 10 quietly turns it back into ten, which is a bug, while volume ?? 10 keeps the zero. One caution: I don't sprinkle question mark dots everywhere, because if a value should always exist, I'd rather get a clear error than hide a real problem.”

Code:
const settings = { volume: 0, theme: "" };
settings.volume || 10       // 10, the zero was lost
settings.volume ?? 10       // 0
settings.theme ?? "light"   // "", empty string kept

const user = {};
const city = user?.address?.city; // undefined, no crash
const onDone = undefined;
onDone?.();                 // skipped, no error
Red flag to avoid:

Using || for defaults where zero or an empty string is valid, or adding ?. everywhere to silence errors.

They may ask next:
  • Does ?. protect you from a variable that was never declared?
  • Why does a || b ?? c give a syntax error?
Say it in 60 seconds
Medium Technical round Fresher Practice question

11. What's the difference between for...in and for...of? Which would you use on an array, and which on a plain object?

What the interviewer is really testing:
Whether you pick the right loop for the data, since the wrong one gives string indexes, stray inherited keys or a TypeError.
Answer frame:
for...in vs for...of
for...inloops over an object's enumerable property keys as strings, including inherited ones.
for...ofloops over the values of an iterable, such as an array, string, Map or Set.

Plain objects: aren't iterable, so use Object.entries with for...of.

Sample spoken answer:

“for...in walks over keys. On an object it gives me each enumerable property name, and it also includes properties inherited through the prototype, which is a surprise if a library added one. On an array it gives me the indexes, but as strings, and it'll also pick up any extra property someone attached to the array. for...of walks over the values of anything iterable: arrays, strings, Maps and Sets. So for an array I use for...of, or a normal for loop if I need the index. A plain object isn't iterable, so for...of on it throws a TypeError. For objects I use Object.entries with for...of and destructure the key and the value, which also gives me only the object's own properties.”

Code:
const scores = [90, 75];
for (const i in scores) console.log(typeof i); // "string" twice
for (const s of scores) console.log(s);        // 90, then 75

const ages = { sam: 21, lee: 23 };
for (const [name, age] of Object.entries(ages)) {
  console.log(name, age);
}
// for (const x of ages) {}  -> TypeError: ages is not iterable
Red flag to avoid:

Using for...in to loop over array values, or trying for...of on a plain object.

They may ask next:
  • How do you get both the index and the value inside a for...of loop?
  • Can you use break inside forEach? What would you use instead?
Say it in 60 seconds
Medium Technical round Fresher Practice question

12. What does 'use strict' do? Name a couple of mistakes it turns into errors.

What the interviewer is really testing:
Whether you know how the language protects you from silent mistakes, and that modern modules already run this way.
Answer frame:

Turning it on: the string at the top of a file or function; ES modules and classes are strict already.

Undeclared variables: assigning to one throws a ReferenceError instead of creating a global.

this: in a plain function call it's undefined, not the global object.

Silent failures: writing to a read-only property throws instead of being ignored.

Sample spoken answer:

“Strict mode is an opt-in that makes JavaScript less forgiving. I turn it on with the string 'use strict' at the top of a file or a function, though ES modules and class bodies are strict automatically. The biggest change is that assigning to a variable I never declared throws a ReferenceError. Without it, a typo like totl = 5 silently creates a global variable, which is a nasty bug to find later. Second, inside a plain function call, this is undefined instead of the global object, so a mistake fails loudly instead of quietly changing global state. It also throws when I write to a read-only property, and it bans duplicate parameter names. I like it because it turns silent mistakes into clear errors early.”

Red flag to avoid:

Thinking strict mode adds type checking or makes the code run faster.

They may ask next:
  • If your project uses ES modules, do you still need to write 'use strict'?
  • Why was strict mode made opt-in instead of simply becoming the default?
Say it in 60 seconds

Async Basics 2 questions

Medium Technical round Fresher Practice question

13. How would you fetch data from an API and show it on the page? What does fetch not do for you when the server returns a 404?

What the interviewer is really testing:
Whether you can do the everyday job of loading data and handle failures, including the fetch detail most beginners miss.
Answer frame:

Request: await fetch(url) gives a Response once the server answers.

Status check: fetch only rejects on network failure, so check res.ok yourself.

Body: await res.json() reads and parses the body; it's a second promise.

States: show loading, then the data or a friendly error.

Sample spoken answer:

“I'd write an async function that awaits fetch with the URL. That gives me a Response object as soon as the server answers. The part beginners miss is that fetch only rejects when the request can't complete at all, like the network being down. A 404 or a 500 still resolves normally, so I check res.ok and throw my own error if it's false. Then I await res.json(), which is a second promise because the body arrives after the headers. I wrap it all in try and catch, so a failure shows a friendly message instead of a blank page. I put the data on the page with textContent, not innerHTML, so text from the server can't run as code. In my project I also showed a loading message while waiting.”

Code:
async function loadUsers(list, message) {
  message.textContent = "Loading...";
  try {
    const res = await fetch("/api/users");
    if (!res.ok) throw new Error(`Request failed: ${res.status}`);
    const users = await res.json();
    list.textContent = users.map((u) => u.name).join(", ");
    message.textContent = "";
  } catch (err) {
    console.error(err);
    message.textContent = "Could not load users. Please try again.";
  }
}
Red flag to avoid:

Assuming the catch block handles a 404, or forgetting that res.json() needs await too.

They may ask next:
  • How would you send a POST request with a JSON body using fetch?
  • How could you cancel a fetch if the user leaves the page before it finishes?
Say it in 60 seconds
Medium Coding round Fresher Practice question

14. Write a sleep function that returns a promise, then use it to print 1, 2 and 3 with a one-second gap between each.

What the interviewer is really testing:
Whether you can turn a callback API into a promise and control the order of async steps in a loop.
Answer frame:

Wrap the timer: create a promise and pass resolve to setTimeout.

Await in a loop: a normal for loop with await runs one step at a time.

Trap: forEach doesn't wait for async callbacks.

Sample spoken answer:

“setTimeout works with a callback, so I wrap it in a promise. The sleep function takes milliseconds and returns a new Promise, and inside it I call setTimeout with resolve as the callback, so the promise settles once the time is up. Then I write an async function with a plain for loop from one to three. Each time round, it awaits sleep of a thousand milliseconds, then logs the number. The key detail is using for or for...of, not forEach. forEach doesn't wait for promises, so with an async callback all three timers would start together and the numbers would print at almost the same moment after one second. Sleep never rejects, so I don't need a catch here, but with real network calls in the loop I'd add one.”

Code:
function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function countUp() {
  for (let i = 1; i <= 3; i++) {
    await sleep(1000);
    console.log(i);
  }
}

countUp(); // 1, 2, 3, one second apart
Red flag to avoid:

Writing a busy while loop to wait, which freezes the page, or expecting forEach to wait for each step.

They may ask next:
  • What would happen if you used forEach with an async callback instead of the for loop?
  • How would you change the loop to run all three waits at the same time?
Say it in 60 seconds

DOM and Browser 3 questions

Easy Technical round Fresher Practice question

15. What is the DOM? How do you find an element and change its text, and why use textContent instead of innerHTML for user input?

What the interviewer is really testing:
Whether you can do basic page updates and know the most common way beginners open a page to script injection.
Answer frame:

DOM: the browser's tree of objects built from the HTML, which JavaScript can read and change.

Finding: querySelector returns the first match or null; querySelectorAll returns a NodeList.

Changing: textContent sets plain text; innerHTML parses the string as HTML.

Safety: user input inside innerHTML can run injected script.

Sample spoken answer:

“The DOM is the tree of objects the browser builds from the HTML. Each tag becomes a node, and JavaScript can read it, change it, add to it or remove from it, and the page updates. To find elements I mostly use querySelector with a CSS selector, which gives me the first match or null, and querySelectorAll, which gives me a NodeList of all matches. getElementById still works and is fine for one element by id. To change text I set textContent. innerHTML parses whatever I give it as HTML, so if that string came from a user, like a comment box, someone could inject an image tag with an onerror handler and run their own script. That's cross-site scripting. So user text goes in textContent, and I only use innerHTML with markup I control.”

Code:
const box = document.querySelector("#greeting");
const input = document.querySelector("#name");
box.textContent = `Hello, ${input.value}`; // shown as plain text
// box.innerHTML = input.value;  // risky: an <img onerror=...> would run

const items = document.querySelectorAll(".item"); // NodeList
items.forEach((el) => el.classList.add("done"));
Red flag to avoid:

Putting user input straight into innerHTML, or not knowing that querySelector returns null when nothing matches.

They may ask next:
  • How is the NodeList from querySelectorAll different from the collection getElementsByClassName returns?
  • How would you create a new list item and add it to the end of a list?
Say it in 60 seconds
Medium Technical round Fresher Practice question

16. Your script says document.querySelector('#btn') is null, but the button is clearly in the HTML. What's going on, and how do you fix it?

What the interviewer is really testing:
Whether you understand how the browser loads a page and scripts, which is behind one of the first bugs every beginner hits.
Answer frame:

Cause: a script in the head runs before the body is parsed, so the button doesn't exist yet.

Fix: add defer so the script runs after parsing, in order.

Other options: put the script at the end of the body, or wait for DOMContentLoaded.

Also check: a typo in the selector, like a missing #.

Sample spoken answer:

“The browser reads HTML from top to bottom, and a normal script tag pauses parsing and runs straight away. If my script is in the head, it runs before the body has been read, so the button doesn't exist yet and querySelector returns null. Then calling addEventListener on null throws. The cleanest fix is the defer attribute: the script downloads in parallel but runs only after the document is parsed, and deferred scripts keep their order. Other options are moving the script to the end of the body, or wrapping the code in a DOMContentLoaded listener. The async attribute is different: it runs as soon as it's downloaded, so it could still run too early. And before blaming timing, I'd check the selector itself, like a missing hash or a typo in the id.”

Red flag to avoid:

Fixing it with a setTimeout delay and hoping the page is ready by then.

They may ask next:
  • What's the difference between the DOMContentLoaded event and the load event?
  • Do scripts with type module behave like defer or like async?
Say it in 60 seconds
Easy Technical round Fresher Practice question

17. What's the difference between localStorage, sessionStorage and cookies? Where would you keep a user's theme choice?

What the interviewer is really testing:
Whether you know where browser data lives, how long it lasts and who can see it.
Answer frame:
localStorage vs sessionStorage vs Cookies
localStoragestays until cleared, shared by every tab of the same origin.
sessionStoragebelongs to one tab and is gone when that tab closes.
Cookiessmall, sent to the server with matching requests, can expire and be HttpOnly.

Strings only: storage holds strings, so objects go through JSON.

Sample spoken answer:

“All three keep data in the browser, but they behave differently. localStorage keeps data until someone clears it, and every tab from the same origin, meaning the same protocol, domain and port, sees it. sessionStorage belongs to one tab and disappears when that tab closes. Cookies are small and, importantly, get sent to the server with every matching request, which is why they're used for login sessions, and the server can mark them HttpOnly so JavaScript can't read them at all. For a theme choice, localStorage is a good fit: it's small, the server doesn't need it and it should survive a restart. Two things I remember: storage only holds strings, so I use JSON.stringify and JSON.parse for objects, and I'm careful with login tokens there, because any script running on the page can read them.”

Code:
localStorage.setItem("theme", "dark");
localStorage.getItem("theme");         // "dark"
localStorage.setItem("prefs", JSON.stringify({ fontSize: 16 }));
const prefs = JSON.parse(localStorage.getItem("prefs"));
sessionStorage.setItem("step", "2");   // gone when the tab closes
Red flag to avoid:

Thinking localStorage is sent to the server, or saving an object without JSON and getting back "[object Object]".

They may ask next:
  • What does getItem return for a key that doesn't exist?
  • Why is it risky to keep a login token in localStorage?
Say it in 60 seconds

Coding Tasks 5 questions

Easy Coding round Fresher Practice question

18. Write a JavaScript function that says whether a sentence like 'Was it a car or a cat I saw?' reads the same backwards once capitals and punctuation are dropped.

What the interviewer is really testing:
Whether you can clean input, handle strings and talk through a simple approach and a better one.
Answer frame:

Clean: lowercase, then keep only letters and digits with a regex.

Compare: reverse and compare, or walk two pointers inward.

Edge cases: empty string, one character, mixed case.

Sample spoken answer:

“First I'd clean the input: lowercase it and remove anything that isn't a letter or a digit with a regular expression, so the car and cat sentence becomes one long lowercase string. The quick version splits it into characters, reverses, joins and compares. It's easy to read but builds a reversed copy. The version I'd write on the board uses two pointers, one at the start and one at the end, moving inward and returning false at the first mismatch. It stops early and needs no reversed copy. I'd mention edge cases out loud: an empty string or a single character counts as a palindrome. And this regex only keeps plain a to z letters, so I'd call that out if the input could contain accented letters.”

Code:
function isPalindrome(text) {
  const s = text.toLowerCase().replace(/[^a-z0-9]/g, "");
  let left = 0;
  let right = s.length - 1;
  while (left < right) {
    if (s[left] !== s[right]) return false;
    left++;
    right--;
  }
  return true;
}

isPalindrome("Was it a car or a cat I saw?"); // true
isPalindrome("hello");                          // false
Red flag to avoid:

Forgetting to clean the string first, so 'Racecar' or a sentence with commas fails.

They may ask next:
  • What's the time and space cost of each version?
  • How would you find the longest palindrome hidden inside a longer string?
Say it in 60 seconds
Easy Coding round Fresher Practice question

19. Remove duplicates from an array of numbers. Show me a one-line way and a way that doesn't use Set.

What the interviewer is really testing:
Whether you know the modern shortcut and can also explain the idea underneath it, including its cost.
Answer frame:

Set: [...new Set(arr)] keeps the first of each value, in order.

Without Set: loop once and track values you've seen in a lookup object.

Cost: filter with indexOf is O(n squared); a lookup keeps it O(n).

Sample spoken answer:

“The one-liner is to put the array into a Set, which only keeps unique values, and spread it back into an array. It keeps the first time each value appears, in the original order. Without Set, the classic answer is filter with indexOf, keeping an item only if its first index equals the current index. It's short, but indexOf scans the array each time, so it's O(n squared) and slow on big lists. A better manual version loops once and uses an object as a lookup of values I've already seen, pushing only new ones into the result. That's O(n). I'd also mention that Set compares objects by reference, so two different objects with the same fields would both stay.”

Code:
const nums = [3, 1, 3, 2, 1];
const unique = [...new Set(nums)]; // [3, 1, 2]

function dedupe(arr) {
  const seen = {};
  const out = [];
  for (const n of arr) {
    if (!seen[n]) {
      seen[n] = true;
      out.push(n);
    }
  }
  return out;
}
dedupe(nums); // [3, 1, 2]
Red flag to avoid:

Only knowing the Set trick and not being able to explain what it does or what the manual version costs.

They may ask next:
  • How would you remove duplicate objects that share the same id?
  • Why could a plain object used as the lookup treat 1 and '1' as the same value?
Say it in 60 seconds
Medium Coding round Fresher Practice question

20. Given a string, return the first character that doesn't repeat. For 'swiss' the answer is 'w'.

What the interviewer is really testing:
Whether you reach for a counting map instead of nested loops, and think about edge cases before being asked.
Answer frame:

Count: one pass builds a map of how often each character appears.

Find: a second pass, in string order, returns the first character with a count of one.

Cost: O(n) time; the map holds one entry per distinct character.

Sample spoken answer:

“I'd do it in two passes. In the first, I loop over the string and count each character in a Map, adding one every time I see it. In the second pass, I loop over the string again, in order, and return the first character whose count is exactly one. For 'swiss', s appears three times, w and i once each, and w comes first, so the answer is w. If nothing is unique I return null, and I'd ask the interviewer whether uppercase and lowercase should count as the same letter. It's O(n) time. The common slow approach is nesting two loops to compare every pair, which works but is O(n squared). I use a Map rather than a plain object because it's built for lookups like this and has no inherited keys to worry about.”

Code:
function firstUnique(str) {
  const counts = new Map();
  for (const ch of str) {
    counts.set(ch, (counts.get(ch) || 0) + 1);
  }
  for (const ch of str) {
    if (counts.get(ch) === 1) return ch;
  }
  return null;
}

firstUnique("swiss"); // "w"
firstUnique("aabb");  // null
Red flag to avoid:

Using nested loops without noticing the cost, or returning the first character from the map instead of from the string.

They may ask next:
  • How would you handle it if the characters arrived one by one as a live stream?
  • What changes if uppercase and lowercase should count as the same letter?
Say it in 60 seconds
Hard Coding round Fresher Practice question

21. Find the second largest number in an array in a single pass, without sorting. What if the largest number appears twice?

What the interviewer is really testing:
Whether you can keep track of state in one loop and handle the duplicate and tiny-array cases that separate a careful fresher.
Answer frame:

Two trackers: keep first and second, both starting at -Infinity.

Update: a bigger number pushes first down to second; a number between them replaces second.

Duplicates: skip values equal to first, so [5, 5, 3] gives 3.

No answer: return null when there's no distinct second value.

Sample spoken answer:

“Sorting works but it's O(n log n), and the default sort compares numbers as strings unless I pass a comparator. In one pass, I keep two variables, first and second, both starting at negative infinity. For each number, if it's bigger than first, the old first moves down to second and the number becomes first. Otherwise, if it's smaller than first but bigger than second, it becomes second. Using strictly smaller than first matters: with five, five, three, the second five doesn't overwrite second, so the answer is three, which is usually what's wanted, though I'd confirm it. At the end, if second is still negative infinity, there's no distinct second value, like an array with one element or all the same number, so I return null.”

Code:
function secondLargest(nums) {
  let first = -Infinity;
  let second = -Infinity;
  for (const n of nums) {
    if (n > first) {
      second = first;
      first = n;
    } else if (n < first && n > second) {
      second = n;
    }
  }
  return second === -Infinity ? null : second;
}

secondLargest([4, 9, 2, 9]); // 4
secondLargest([7]);          // null
Red flag to avoid:

Sorting without a comparator, or returning the largest number again when it appears twice.

They may ask next:
  • How would you change this to find the k-th largest number?
  • Why does nums.sort()[nums.length - 2] give the wrong answer for [9, 10]?
Say it in 60 seconds
Hard Coding round Fresher Practice question

22. Write a function that checks whether two objects are deeply equal, including nested objects and arrays. Why doesn't === work here?

What the interviewer is really testing:
Whether you understand reference equality and can write a clean recursive function while being honest about what it doesn't cover.
Answer frame:

Why === fails: it compares references, so two separate objects with the same content aren't equal.

Base cases: equal with ===, true; either not an object or null, false.

Recurse: same number of keys, then compare each key's value deeply.

Limits: say what you skip, such as Dates, Maps, NaN and objects that refer to themselves.

Sample spoken answer:

“Triple equals on objects compares references, so two separate objects with identical content are still not equal. My function starts with a quick check: if the two values are triple-equal, return true. If either one isn't an object, or is null, they can't be deeply equal, so return false. I also return false when one is an array and the other isn't. Then I get both lists of keys with Object.keys. If the counts differ, false. Otherwise, for every key, I check the other object has it as its own key, and call the function again on the two values, stopping at the first mismatch. Arrays work too, because their indexes are keys. I'd tell the interviewer what this skips: Dates, Maps, NaN and objects that refer to themselves.”

Code:
function deepEqual(a, b) {
  if (a === b) return true;
  if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
    return false;
  }
  if (Array.isArray(a) !== Array.isArray(b)) return false;
  const keysA = Object.keys(a);
  const keysB = Object.keys(b);
  if (keysA.length !== keysB.length) return false;
  return keysA.every((key) => Object.hasOwn(b, key) && deepEqual(a[key], b[key]));
}

deepEqual({ x: [1, { y: 2 }] }, { x: [1, { y: 2 }] }); // true
deepEqual({ x: 1 }, { x: "1" });                       // false
Red flag to avoid:

Comparing JSON.stringify strings and calling it done, which fails when the same keys come in a different order.

They may ask next:
  • How would you stop it looping forever on an object that refers to itself?
  • Why is comparing the output of JSON.stringify a weak shortcut for this?
Say it in 60 seconds

Projects 1 question

Medium Behavioral round Fresher Practice question

23. Walk me through a JavaScript project you built in college, an internship or a bootcamp. What part did you write yourself, and what was the hardest bug?

What the interviewer is really testing:
Whether you really wrote the code on your resume and can talk about it in depth, including a bug you tracked down yourself.
Answer frame:

The project: what it did and who used it, in two sentences.

Your part: the specific pieces you wrote, not the team's whole feature list.

The bug: what broke, how you narrowed it down, the fix.

Looking back: one honest thing you'd do differently.

Sample spoken answer:

“In my final year I built a small expense-splitting web app with two classmates, using plain JavaScript on the front end and a simple Node API. I owned the front end: the form to add expenses, the list and the running balances. The hardest bug was that clicking delete sometimes removed the wrong expense. I stepped through it with breakpoints in the browser dev tools and saw that each delete button remembered its position in the list from when it was first drawn, so after one delete the positions shifted. I fixed it by giving every expense an id, storing it on the button in a data attribute and deleting by id instead. Looking back, I'd write a few small tests for the balance maths, because I checked those by hand every time.”

Red flag to avoid:

Describing only what the team built, or being unable to explain how your own part of the code works.

They may ask next:
  • If I opened your repository now, which file would you be proudest of, and why?
  • What would break first if a hundred people used the app at the same time?
Say it in 60 seconds

Working Style 1 question

Medium Situational round Fresher Practice question

24. In a group project, a teammate pasted a big block of JavaScript from an online answer into your app. It works, but nobody on the team understands it. What do you do?

What the interviewer is really testing:
Whether you see code nobody can explain as a real risk and can raise it with a teammate calmly, which is how you'll need to act in a first job too.
Answer frame:

Talk to them: raise it with the teammate directly, not in front of the group.

Understand it: read it together until someone can explain every line.

Check the risks: innerHTML with user input, stray globals, and whether the source or your course allows reuse.

Decide: keep it with a comment and a credit, or rewrite the small part you really need.

Sample spoken answer:

“I wouldn't rip it out or make a fuss in the group chat. First I'd sit down with my teammate and read it together, stepping through it in the browser dev tools if that helps, until at least one of us can explain every line. Working code that nobody understands is a risk. If it breaks the night before the demo, nobody can fix it, and the examiner might ask any of us how it works. I'd also check a few basics: does it put user input into innerHTML, does it create global variables, and are we allowed to reuse it under the source's licence and our course rules. If it passes, we add a short comment saying what it does and where it came from. If it's too tangled, I'd suggest we rewrite just the part we need, smaller and in our own style.”

Red flag to avoid:

Keeping code nobody can explain just because it works, or calling the teammate out in front of the group.

They may ask next:
  • What would you do if your teammate says there's no time to change it before the deadline?
  • How would you check that the pasted code is safe to run on your page?
Say it in 60 seconds
Were you asked something else? Share it A person checks every question before it goes on the site. No name is shown.
For the call itself

You practiced these. On the real call, ClapAssist helps with the rest.

ClapAssist is an AI interview assistant for Mac and Windows. It listens to the interview on your computer and shows you what to say, in short lines you can read while you talk. Your live interview audio and screen are never stored. Your resume and notes are saved to your account so the app fills them in on any computer. It stays out of screen share on every plan, including Free; only you can see it.

Download with 10 free minutes
Mac and Windows · Stays out of screen share · No card