Hey fellow devs! 👋 If you're prepping for a frontend interview in 2025, buckle up! You’re gonna face JavaScript fundamentals, tricky async stuff, and some brain-teasing real-world problems. Let's get you ready with 12 must-know questions (and answers) so you can crush your next interview! 💪🔥
1️⃣ var
vs. let
vs. const
– What’s the deal? 🤔
-
var
= Function scope, hoisted like a magic trick 🪄 (but can be messy). -
let
= Block scope, no redeclaration, safer! -
const
= Likelet
but locked in (you can’t reassign it, but you can mutate objects!).
👉 Rule of thumb: Use const
by default, let
when needed, and avoid var
like it’s a memory leak.
2️⃣ How does JavaScript handle async operations? 🤯
JavaScript is single-threaded but deals with async stuff using:
- Callbacks (old-school, hello callback hell 👿)
-
Promises (
.then()
&.catch()
make life easier) - Async/Await (the cleanest way to handle async code)
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
👉 Use async/await. Your future self will thank you. 😎
3️⃣ Explain the Event Loop like I’m 5 🎡
The Event Loop is what keeps JavaScript non-blocking and fast. 🏎️
- Call Stack: Runs sync code first.
-
Task Queue: Holds async callbacks (like
setTimeout
). - Microtask Queue: Holds promises, gets priority over Task Queue.
👉 Ever wondered why setTimeout(() => console.log(‘Hi’), 0)
doesn’t run immediately? Because promises cut the line! ⏳
4️⃣ Closures: What, why, and when? 🧐
A closure is a function that remembers variables from its outer scope even when the outer function has finished executing. 🧠
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2
👉 Closures are 🔥 for data encapsulation, private variables, and function factories.
5️⃣ Prototypal Inheritance – What’s the magic? ✨
JavaScript doesn’t use classical OOP inheritance (like Java or C#). Instead, it uses prototypes. Every object has a hidden __proto__
that links to another object. 🧬
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, I’m ${this.name}!`);
};
const user = new Person('Alice');
user.sayHello(); // Hello, I’m Alice!
👉 Prototypes are the backbone of JavaScript's object system! Modern syntax? Use class
!
6️⃣ Shallow vs. Deep Copy – Clone Wars 🏴☠️
- Shallow Copy = Only copies the first level, deeper objects are still referenced.
- Deep Copy = Fully clones an object, including nested structures.
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
shallowCopy.b.c = 42;
console.log(obj.b.c); // 42 (Oops! 😱)
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 100;
console.log(obj.b.c); // 42 (Phew! 🎉)
7️⃣ ==
vs. ===
– The Battle of Equality ⚔️
-
==
does type coercion (sometimes useful, mostly dangerous). -
===
is strict (always prefer it!).
console.log(5 == '5'); // true (😬 weird but true)
console.log(5 === '5'); // false (👍 expected behavior)
👉 Just use ===
. Unless you enjoy debugging nightmares. 😆
8️⃣ Generators – The Pause Button ⏸️
Generators are functions that can pause and resume execution. Perfect for iterators and async flows!
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
9️⃣ What’s up with this
? 🤨
this
is the most confusing keyword in JavaScript.
- Global =
window
(orundefined
in strict mode). - Object method = Refers to the calling object.
- Arrow function = Inherits
this
from its surrounding scope.
const obj = {
name: 'Alice',
sayName() {
console.log(this.name);
},
};
obj.sayName(); // Alice
👉 Pro tip: If this
is acting weird, check how the function is called! 🧐
🔟 Debouncing & Throttling – The Speed Limit 🚦
- Debouncing = Delays function execution until after a certain time has passed.
- Throttling = Ensures a function runs at most once in a given period.
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
const handleResize = debounce(() => console.log('Resized!'), 300);
window.addEventListener('resize', handleResize);
1️⃣1️⃣ Memory Leaks – Avoiding JavaScript Hoarding 🗑️
Common memory leak causes:
- Uncleared event listeners 🛑
- Global variables hanging around 🎭
- Detached DOM elements 👻
- Closures holding onto large objects 🎒
✅ Fix: Use WeakMap
, remove event listeners, and clean up DOM nodes properly!
1️⃣2️⃣ map()
, forEach()
, or reduce()
? 🤷♂️
-
map()
→ Returns a new array. -
forEach()
→ Loops, but doesn’t return a new array. -
reduce()
→ Reduces an array to a single value.
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2); // [2, 4, 6]
const sum = nums.reduce((acc, n) => acc + n, 0); // 6
🔥 That’s a wrap! If you found this useful, share it with your dev friends! 🚀 Let’s ace those interviews! 💼