Top 10 JavaScript Coding Challenges for Senior Developers
Introduction
In senior developer interviews, you aren't just asked to write code that works; you're asked to explain how it works. Topics like Closures, the Event Loop, and Prototypal Inheritance are favorites for interviewers looking to test depth of knowledge.
Here are 10 coding challenges that test your understanding of core JavaScript mechanics. Try to solve them before looking at the answers!
Part 1: Closures & Scope
Challenge 1: The Classic Loop
What will the following code log?
<details> <summary><strong>Click to Reveal Solution</strong></summary>for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1); }
Output: 3, 3, 3
Explanation: The variable i is declared with var, which has function scope (or global scope here), not block scope. The loop finishes running before the setTimeout callbacks execute. By then, i has effectively become 3. To fix this, use let (block scope) instead of var.
Challenge 2: Private Counter
Create a function createCounter that returns an object with increment and getValue methods. The value should be private and not accessible directly.
<details> <summary><strong>Click to Reveal Solution</strong></summary>const counter = createCounter(); counter.increment(); console.log(counter.getValue()); // 1 console.log(counter.count); // undefined
function createCounter() { let count = 0; // Private variable return { increment: () => { count++; }, getValue: () => count }; }
Explanation: This utilizes a Closure. The returned methods retain access to the count variable from their lexical scope, even after createCounter has returned.
Challenge 3: this Context
What gets logged here?
<details> <summary><strong>Click to Reveal Solution</strong></summary>const object = { who: 'World', greet() { return `Hello, ${this.who}!`; }, farewell: () => { return `Goodbye, ${this.who}!`; } }; console.log(object.greet()); console.log(object.farewell());
Output:
Hello, World!Goodbye, undefined!(or window/global object)
Explanation: Regular functions (greet) define this based on how they are called. Arrow functions (farewell) capture this from the surrounding lexical context (where they were defined). Since object isn't a scope, the arrow function sees the global scope (or undefined in strict mode).
Part 2: Event Loop & Async
Challenge 4: Microtasks vs Macrotasks
What is the order of logs?
<details> <summary><strong>Click to Reveal Solution</strong></summary>console.log('1'); setTimeout(() => console.log('2'), 0); Promise.resolve().then(() => console.log('3')); console.log('4');
Output: 1, 4, 3, 2
Explanation:
- Synchronous code (
1,4) runs first. - Promises create Microtasks (
3), which have higher priority than Macrotasks. setTimeoutcreates a Macrotask (2), which runs after the microtask queue is empty.
Challenge 5: Async Iterator
What needs to change to make this work?
<details> <summary><strong>Click to Reveal Solution</strong></summary>const urls = ['url1', 'url2']; urls.forEach(async (url) => { const content = await fetch(url); console.log('Done'); }); console.log('All Done');
Issue: forEach does not wait for async callbacks. 'All Done' will log before the fetches finish.
Fix: Use for...of or Promise.all.
</details>// Correct approach await Promise.all(urls.map(async (url) => { await fetch(url); console.log('Done'); })); console.log('All Done');
Part 3: Array Methods & Logic
Challenge 6: Flattening Arrays
Write a function using reduce to flatten a nested array: [[1, 2], [3, 4], [5]] -> [1, 2, 3, 4, 5].
</details>const data = [[1, 2], [3, 4], [5]]; const flat = data.reduce((acc, curr) => acc.concat(curr), []); // Or simpler in modern JS: data.flat()
Challenge 7: Object References
What's the output?
<details> <summary><strong>Click to Reveal Solution</strong></summary>const check = {}; const a = { key: 'a' }; const b = { key: 'b' }; check[a] = 123; check[b] = 456; console.log(check[a]);
Output: 456
Explanation: Object keys are strings. Both a and b are objects, and when converted to a string key, they both become "[object Object]". So check actually looks like { "[object Object]": 456 }. The second assignment overwrites the first.
Challenge 8: Sparse Arrays
What is arr.length?
<details> <summary><strong>Click to Reveal Solution</strong></summary>const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length);
Output: 11
Explanation: Arrays in JS are just objects with numeric keys. Assigning index 10 expands the length to 11. Indexes 3 through 9 are "empty slots" (sparse).
</details>Conclusion
How many did you get right?
- 8-10: You are Senior level ready!
- 5-7: Good grasp, but review the Event Loop.
- 0-4: Time to brush up on "You Don't Know JS".
Mastering these concepts isn't just about passing interviews; it's about avoiding bugs that only show up in complex, real-world applications. Happy coding!
Recommended Posts
How to Make Money Online in 2026: The Ultimate AI Guide
Stop trading time for money. In 2026, the key to online income is AI Automation and Digital Products. Learn the most effective strategies now. ২০২৬ সালে অনলাইন আয়ের সেরা উপায়গুলো জানুন।
Google Adding Blur to Android 17’s System UI on Pixel
Google is introducing significantly more blur across Android 17 on Pixel devices, following the Material 3 Expressive redesign. অ্যান্ড্রয়েড ১৭-এ আসছে নতুন ব্লার ইফেক্ট।
Server vs Client Components: কখন কোনটি ব্যবহার করবেন? (বিস্তারিত গাইড)
Next.js App Router এ Server এবং Client Components নিয়ে কনফিউশন? জানুন কখন 'use client' লিখবেন আর কখন Server Component এর পাওয়ার ব্যবহার করবেন।