05 / Article
JavaScript is one of the most asked languages in frontend interviews. This guide covers the 12 most important questions — explained simply, with real code examples.
All three are used to declare variables, but they behave differently.
var — old way, function-scoped, causes bugs. Avoid it.
let — block-scoped, value can be changed. Use when value needs to update.
const — block-scoped, value cannot be reassigned. Use this by default.
let age = 25;
age = 26; // ✅ allowed
const name = "Raj";
name = "Amit"; // ❌ TypeErrorSimple rule: Always start with const. Change to let only when needed.
A closure is when an inner function remembers variables from its outer function — even after the outer function has finished running.
Think of it like a backpack. The function carries its surrounding variables wherever it goes.
function makeCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
Closures are often used for data privacy and state management.
== compares values after type conversion.
=== compares both value and type.
0 == false; // true
0 === false; // false
null == undefined; // true
null === undefined; // false
Best practice: Always use ===.
Both represent absence of value, but for different reasons.
undefined means a variable has been declared but not assigned.
null means you intentionally assigned an empty value.
let a;
console.log(a); // undefined
let b = null;
console.log(b); // null
typeof a; // "undefined"
typeof b; // "object"
The typeof null behavior is a historical JavaScript bug that remains for compatibility.
JavaScript is single-threaded, meaning it executes one task at a time.
The Event Loop allows JavaScript to handle asynchronous operations efficiently.
Process:
Code runs in the Call Stack.
Async tasks are handled by browser APIs.
Completed callbacks enter a queue.
Event Loop pushes callbacks back to the Call Stack.
console.log("1");
setTimeout(() => console.log("3"), 0);
Promise.resolve().then(() => console.log("2"));
console.log("4");
Output:
1
4
2
3Promises execute before setTimeout.
A Promise represents a future value.
States:
Pending
Fulfilled
Rejected
fetch("https://api.example.com/user")
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err));
Promises help manage asynchronous code more effectively.
async/await is syntactic sugar built on top of Promises.
It makes asynchronous code look synchronous and easier to read.
async function getUser() {
try {
const res = await fetch("/api/user");
const data = await res.json();
console.log(data);
} catch (err) {
console.log(err);
}
}
Benefits:
Cleaner code
Better readability
Easier error handling
The value of this depends on how a function is called.
const user = {
name: "Dheeraj",
greet() {
console.log(this.name);
}
};
user.greet();
Output:
Dheeraj
Arrow functions do not have their own this.
const user = {
name: "Priya",
greetArrow: () => {
console.log(this.name);
}
};This usually produces undefined.
Destructuring allows extracting values from objects and arrays easily.
Object destructuring:
const user = {
name: "Raj",
age: 25
};
const { name, age } = user;
console.log(name);
console.log(age);Array destructuring:
const [first, second] = [10, 20];
console.log(first);
console.log(second);It improves readability and reduces repetitive code.
These are powerful array methods frequently used in modern JavaScript and React.
Transforms every item.
const nums = [1, 2, 3];
const doubled = nums.map(num => num * 2);
console.log(doubled);
Output:
[2, 4, 6]Keeps items matching a condition.
const nums = [1, 2, 3, 4, 5];
const result = nums.filter(num => num > 3);
console.log(result);Output:
[4, 5]Combines values into a single result.
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, curr) => acc + curr, 0);
console.log(sum);Output:
10Both improve application performance.
Waits until the user stops triggering an event before executing.
Common use case: Search bars.
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
fn(...args);
}, delay);
};
}Limits execution to once every fixed interval.
Common use case: Scroll events.
function throttle(fn, delay) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn(...args);
}
};
}A Higher-Order Function is a function that:
Takes another function as an argument
Returns a function
Example:
function multiplyBy(factor) {
return function (num) {
return num * factor;
};
}
const double = multiplyBy(2);
console.log(double(5));
Output:
10Common Higher-Order Functions:
map()
filter()
reduce()
setTimeout()
addEventListener()
Think out loud while solving problems.
Ask clarifying questions before coding.
Focus on readability over clever tricks.
Explain trade-offs in your approach.
Stay calm if you don't know an answer immediately.
Interviewers evaluate your problem-solving process, not just the final answer.
JavaScript interviews often focus on a few core concepts repeatedly. Understanding closures, promises, async/await, the event loop, array methods, and scope will help you answer a large percentage of frontend interview questions confidently.
Master these 12 topics, practice coding examples, and you'll be much better prepared for your next JavaScript interview.
Good luck and keep building! 🚀
06 / Continue Reading
More articles related to #javascript/#interview/#frontend


About the Author
Full Stack Developer focused on Next.js, React, TypeScript and modern web development. I share practical guides, things I build, problems I solve and lessons I learn along the way.