Absolutely!
Here's a curated list of JavaScript coding challenges designed to
sharpen your skills for high-level interviews. These focus on algorithms,
data structures, advanced language features, and real-world patterns (like
debouncing, throttling, etc.).
🔥 High-Interview-Level JavaScript Challenges
1. Implement Deep Clone
Description: Write a function deepClone(obj) that returns a deep copy of the input
object.
Handle nested objects and arrays.
Ignore functions and circular references for now.
2. Custom Promise.all
function customPromiseAll(promises) {
// Your code here
}
Goal: Accept an array of promises and return a new promise that resolves when all
promises resolve or rejects when any reject.
3. LRU Cache
Build an LRU (Least Recently Used) cache class in JS.
class LRUCache {
constructor(capacity) {}
get(key) {}
put(key, value) {}
}
Constraints:
O(1) time for get and put.
Use a Map and Doubly Linked List.
4. Throttle / Debounce
Implement these two functions:
function debounce(fn, delay) {}
function throttle(fn, delay) {}
Bonus: Show usage in a real-world scroll or input event listener.
5. Chained Sum Function
sum(1)(2)(3)...(n) == total
Usage:
sum(1)(2)(3)(4)(); // 10
Hint: Use valueOf() or toString() overriding.
6. Event Emitter (Pub/Sub System)
Build a custom EventEmitter class.
const emitter = new EventEmitter();
emitter.on('click', () => console.log('clicked'));
emitter.emit('click');
Add:
.off(eventName, callback)
.once(eventName, callback)
7. Memoization
Create a memoize(fn) that caches the output of pure functions.
const memoizedAdd = memoize((a, b) => a + b);
Bonus: Handle arguments of any type (objects, arrays, etc.).
8. Asynchronous Retry Logic
Write a function that retries a failed async operation:
async function retry(fn, retries, delay) {}
Usage:
await retry(fetchData, 3, 1000); // Retry 3 times, 1s delay
9. Implement JSON.stringify
Custom polyfill for JSON.stringify(obj).
Handle:
Primitives
Arrays
Nested objects
undefined, functions, and symbols should be omitted like the real
JSON.stringify
10. Virtual DOM Diffing
Create a function that compares two virtual DOM trees and returns a list of changes
(add, remove, update).
diff(oldVNode, newVNode) → [patches]
You don’t need to build a real VDOM renderer, just structure diff output.
11. Flatten Object
Convert a nested object into a flat object:
flatten({
a: 1,
b: {
c: 2,
d: { e: 3 }
}
})
Output:
{
'a': 1,
'b.c': 2,
'b.d.e': 3
}
12. Binary Search Tree Checker
Given an object representing a binary tree, write a function to check if it is a valid
BST.
13. Recreate bind / call / apply
Rebuild them from scratch.
Function.prototype.myBind = function (ctx, ...args) {}
14. Implement a Scheduler
Implement a simple task scheduler that limits how many tasks can run concurrently.
15. Build a Tiny Parser
Parse this:
"3 + (2 * (1 + 1))"
Into an AST (Abstract Syntax Tree).
Bonus: Evaluate it too.
🧠 Tips
Focus on readability and efficiency.
Always talk about time/space complexity.
Use ES6+ features confidently, but know how they work under the hood.
Would you like solutions, unit tests, or want to pick any one to do now together?