JAVASCRIPT CODING
JavaScript problems
160 problems for the JavaScript coding round: write debounce, Promise.all, deep clone, an event emitter, polyfills, and real DOM widgets in the editor, and run tests that say exactly what works and what doesn't. 47 easy, 82 medium, and 31 hard.
Not algorithm puzzles (the DSA section has those): these test the language and the browser. Everything runs on this page, your code is saved as you go, and hints are free. Sign in with Google to see the solutions.
160 of 160 problems
Timing
- DebounceWait until calls stop for
waitms, then call the function once with the latest arguments. - ThrottleRun a function right away, then at most once every
waitms, dropping the calls in between. - setInterval with setTimeoutRebuild
setIntervalandclearIntervalfrom chainedsetTimeoutcalls. - Clear all timeoutsMake timeouts through an object that remembers them, so one call can cancel every timeout it started.
- Stopwatch with lapsBuild a stopwatch that starts, stops, records laps, and resets, and stays exact to the millisecond.
- Throttle with a trailing callRun a function at most once every
waitms, and once more at the end with the latest arguments. - Idle timerTell when the user has been inactive for
timeoutms, and when they come back, from events on a target. - Countdown timer with pause and resumeCount down in whole seconds, and pause and resume without losing the part of a second already counted.
- Poll until a condition holdsCall a check every
intervalms until it returns something truthy, and give up with an error aftertimeoutms. - Task scheduler with delaysRun tasks one at a time, in order, each a given delay after the previous one has finished.
- Rate limiterStart at most
limitcalls in anyintervalms, queue the rest, and return a promise of each result. - Batch callsCollect items for
waitms, or until there aremaxSizeof them, then pass them all to one call of a function. - Interval that corrects its own driftRun a function on a fixed schedule that late timers can't push back, skipping ticks that are already overdue.
- Debounce with leading, trailing, and maxWaitA debounce that can run at the start of a burst, at the end, or both, and at least every
maxWaitms. - Debounce async calls, latest winsDebounce an async function so every call gets a promise, and only the latest call ever gets a result.
Functions
- OnceWrap a function so it runs only on the first call, and every later call returns that first result.
- Counter with private stateBuild a counter whose count lives in a closure, so only its methods can read or change it.
- Chainable calculatorReturn an object whose methods each return it, so calls chain:
calculator(2).add(3).multiply(4).value()is 20. - ComposeCombine functions right to left into one, so
compose(f, g)(x)isf(g(x)). - PipeCombine functions left to right into one, so
pipe(f, g)(x)isg(f(x)). - Before and afterLimit a function by call count:
beforeruns it only for the first calls,afteronly from the nth call on. - Partial applicationFix some of a function's arguments now, with placeholders for gaps, and pass the rest later.
- CurryCollect a function's arguments over several calls and call it once it has as many as it declares.
- Infinite curry sumWrite
sumsosum(1)(2)(3)()is 6: each call adds its numbers, and a call with no arguments returns the total. - MemoizeCache a function's results by all of its arguments, compared the way a
Mapcompares keys. - Memoize with a key resolver and size limitCache results under a key you choose, and drop the least recently used entry when the cache is full.
- Memoize object arguments with a WeakMapCache results by every argument, but hold object arguments only as
WeakMapkeys, so the cache never keeps them in memory. - Build a spyWrite
createSpy: a function that records its calls, theirthis, results, and errors, likejest.fn(). - TrampolineRun a recursive function that returns thunks in a loop, so it can go 100,000 steps deep without overflowing the stack.
- Curry with placeholdersCurry a function, with a placeholder that reserves a position to fill in a later call.
- Memoize an async functionCache an async function's promises by key: share calls in flight, keep results, and forget failures so the next call tries again.
- Compose middleware like KoaRun Koa-style middleware: each gets the context and a
next()that runs the rest of the chain and returns a promise.
Promises & async
- SleepReturn a promise that fulfills after
msmilliseconds, soawaitcan pause an async function. - PromisifyTurn a Node-style callback function into one that returns a promise.
- Run async tasks in seriesRun async tasks one after another, each starting when the previous one finishes, and collect their results.
- Promise.raceSettle the same way as the first input to settle, as
Promise.racedoes. - promisifyAllGive every callback method of an object a promise-returning
nameAsynctwin, including the methods it inherits from its class. - Promise.allFulfill with every input's value in order, or reject as soon as one input rejects, as
Promise.alldoes. - Promise.allSettledWait for every input to settle and report each outcome, in order, as
Promise.allSettleddoes. - Promise.anyFulfill with the first input to fulfill, or reject with an
AggregateErroronce they've all failed, asPromise.anydoes. - Promise with a timeoutReject with a
TimeoutErrorif a promise takes longer thanmsto settle, and leave no timer behind. - Wait for an event, with a timeoutTurn an emitter's next
eventinto a promise that rejects on an"error"event or a timeout, and leaves no listener or timer behind. - Race that aborts the losersStart async tasks together, settle like the first one to finish, and abort every other task through its own
AbortSignal. - Async pipeChain sync and async functions left to right, awaiting each step before passing its result on.
- Retry with exponential backoffCall an async function again when it fails, waiting longer before each new attempt.
- Dedupe in-flight requestsShare one in-flight promise between callers asking for the same key, and start fresh once it settles.
- Stale-while-revalidate cacheServe cached values at once, refresh stale ones in the background, and keep at most one fetch per key in flight.
- DataLoader-style batch loaderCollect the
load(key)calls made in one tick into a singlebatchFn(keys)call, and give each caller its own result. - Map with a concurrency limitRun an async function over a list with at most
limitcalls at a time, and keep the results in input order. - Async task queue with pause and resumeBuild a queue that runs async tasks with a concurrency limit, hands each caller its task's result, and can pause and resume.
- Cancellable task with AbortControllerRun an async task with an
AbortSignal, and cancel it so its promise rejects at once, even if the task ignores the signal.
Iterators & generators
- Fibonacci generator with takeWrite an endless Fibonacci generator, and a lazy
take(iterable, n)that yields the firstnvalues of any iterable. - Make a linked list iterableGive a linked list class a
[Symbol.iterator]so it works withfor...ofand spread, and aLinkedList.from(iterable)to build one. - Zip iterablesPair up the values of several iterables, position by position, stop at the shortest, and close the others.
- Interleave iterables round-robinTake one value from each iterable in turn, skip the ones that run out, and carry on until all of them are done.
- Flatten nested iterablesLazily yield the values inside nested arrays, Sets, and generators, keeping strings whole, down to an optional depth.
- Lazy iterator helpersBuild
lazy(iterable)with chainablemap,filter, andtakethat do no work untiltoArray()or a loop asks for values. - Async iterator over a paginated APITurn a page-by-page fetcher into an async iterable of items that fetches each page only when it's needed.
- Run a generator as a coroutineWrite
run(genFn, ...args): drive a generator that yields promises, resuming it with each result, the wayasyncandawaitwork. - Merge async iterablesCombine several async iterables into one that yields each value as soon as any source produces it, and closes the sources when it stops.
- Turn events into an async iteratorWrite
on(target, type): an async iterator over events that buffers the ones nobody is waiting for and removes its listener onreturn().
Polyfills
- Array.prototype.mapWrite
myMap, a polyfill formap: a new array of callback results, withthisArg, holes kept as holes. - Array.prototype.filterWrite
myFilter, a polyfill forfilter: keep the elements whose callback result is truthy, skipping holes. - Array.prototype.some and everyWrite
mySomeandmyEvery, polyfills forsomeandevery: stop at the element that settles the answer, and return a boolean. - Array.prototype.includesWrite
myIncludes, a polyfill forincludes: compare like===but findNaN, read holes asundefined, and start atfromIndex. - Object.createWrite
Object.myCreate, a polyfill forObject.create: a new object with a chosen prototype, evennull. - The instanceof operatorWrite
myInstanceOf(value, Constructor): walk the prototype chain to answer whatinstanceofwould. - Function.prototype.callWrite
myCall, a polyfill forcall: run a function with a chosenthis, withoutcall,apply, orbind. - The new operatorWrite
myNew(Constructor, ...args): create the object, link its prototype, run the constructor, pick the result. - Array.prototype.reduceWrite
myReduce, a polyfill forreduce, with its rules for a missing initial value, holes, and empty arrays. - Array.prototype.flatWrite
myFlat(depth), a polyfill forflat: spread nested arrays into one, down to a depth, dropping holes. - Array.prototype.sortWrite
mySort, a polyfill forsort: a stable sort in place, comparing as strings by default, withundefinedand holes moved to the end. - Array.fromWrite
Array.myFrom, a polyfill forArray.from: turn iterables and array-likes into arrays, with an optional mapFn. - Object.groupBy and Map.groupByWrite
Object.myGroupByandMap.myGroupBy: put the items of any iterable into groups by key, in an object with no prototype or in a Map. - Object.assignWrite
Object.myAssign, a polyfill forObject.assign: copy own enumerable keys, symbols included, with get and set. - Promise.prototype.finallyWrite
myFinally, a polyfill forfinally: run cleanup on either outcome and pass the original result through. - Function.prototype.bindWrite
myBind, a polyfill forbind: a fixedthis, preset arguments, and correct behaviour withnew. - A promise from scratchBuild
MyPromisewiththen,catch,resolve, andreject: microtask callbacks, chaining, and thenables. - JSON.stringifyWrite
JSON.myStringifyfor plain data: escaped strings, skipped values,toJSON, and aTypeErroron cycles. - JSON.parseWrite
JSON.myParse: turn JSON text into the value it describes, and throw aSyntaxErrorthat says where for anything JSON doesn't allow.
Objects & data
- Get by pathRead a nested value by a path like
a.b[0].c, and fall back to a default when anything on the way is missing. - pick and omitMake a new object with only some of an object's keys, or with all of them but some.
- isEmptyTell whether any value holds nothing: empty strings, arrays, Maps, Sets, and objects, but never numbers or functions.
- shallowEqualCompare two objects one level deep, key by key with
Object.is, the way React decides whether props changed. - Camelize keysTurn every snake_case key of an API response into camelCase, at every depth, without touching the values.
- Deep freezeFreeze an object and everything reachable from it, including symbol keys, functions, and cycles.
- Set by pathWrite a nested value by a path like
a.b[0].c, creating objects and arrays on the way, without allowing prototype pollution. - Immutable setInReturn a copy with one nested value changed, copying only the objects on the path and sharing every other branch.
- Flatten an objectTurn a nested object into a single level whose keys are dotted paths, like
user.tags.0. - Unflatten an objectRebuild a nested object, with arrays where keys are indexes, from an object whose keys are dotted paths.
- Compact an objectDrop
null,undefined, and empty objects and arrays at every depth, including ones that only become empty on the way. - Deep mergeMerge objects into a new one, recursively for nested objects, with later values winning and no prototype pollution.
- Object diffCompare two objects and list the dotted paths that were added, removed, and changed.
- Normalize nested dataTurn nested API data into tables of items by id, with every nested item replaced by its id, following a schema.
- Deep equalCompare two values by structure and contents, including Map, Set, Date, RegExp, prototypes, and cycles.
- Deep cloneCopy any value all the way down, including Map, Set, Date, class instances, shared references, and cycles.
- Apply a JSON PatchApply
add,remove, andreplaceoperations at JSON Pointer paths, returning a new document and failing cleanly on bad paths.
Arrays & collections
- Chunk an arraySplit an array into groups of
sizeitems, with whatever is left over in a shorter last group. - Partition an arraySplit an array in two in one pass: the items that pass a test, and the items that don't.
- uniqueByRemove duplicates by a key, a property name or a function, keeping the first item for each key, in order.
- zip and unzipPair up the items of several arrays by index, padding short arrays with
undefined, and split the pairs back apart. - Move an item in a listReturn a copy of a list with one item moved to a new index, the way a list reorders after drag and drop.
- sortedIndex with binary searchFind where a value belongs in a sorted array, before or after equal items, reading only O(log n) items.
- Set operations by keyIntersect, subtract, and merge two arrays of objects by a key such as
id, keeping one item per key. - Fisher–Yates shuffleShuffle a copy of an array so every order is equally likely, using a random function that tests can replace.
- sortBy with several keysSort a copy of an array by several keys, each ascending or descending, stably, with missing values last.
- Build a tree from a flat listTurn a flat list of items with
idandparentIdinto a nested tree in O(n), keeping order and catching cycles.
Classes & state
- Undo/redo historyA class that holds a value and its history, so you can step back with undo and forward again with redo.
- Iterable Range classMake a Range class work with for...of and spread by writing its iterator by hand.
- TTL cacheA cache whose entries expire a set number of milliseconds after they're stored.
- combineReducersCombine reducers that each own one key of the state into a single reducer for the whole state.
- Form validatorA class that checks a form's values against rules and returns, for each failing field, the message of its first failing rule.
- Event emitterAn EventEmitter class with on, off, once, and emit that stays correct when listeners change during an emit.
- LRU cacheA fixed-size cache with O(1) get and put that drops the least recently used entry when it's full.
- Redux-style storecreateStore(reducer, initialState) with getState, dispatch, and subscribe, the core of Redux.
- Redux applyMiddlewareapplyMiddleware(...middlewares) wraps a Redux store's dispatch in a chain of middleware that can log, change, or stop actions.
- PubSub with wildcard topicsA publish/subscribe hub whose subscriptions can use
*and**to match whole groups of dot-separated topics. - Client-side routercreateRouter(routes) with resolve(url): match paths like /users/:id, capture and decode params, and support a final * wildcard.
- Finite state machinecreateMachine(config): a machine that moves between named states on events, with guarded transitions.
- Toast queueA class that shows at most N toasts at once, queues the rest, and dismisses each one a set time after it appears.
- Async mutexA lock for async code: one holder at a time, and everyone else waits their turn in order.
- Observable with map and filterA lazy Observable class with subscribe, unsubscribe, teardown, and chainable map and filter operators.
- Reactivity with ProxyVue-style reactivity: reactive(object) returns a Proxy that tracks reads, and watchEffect(fn) reruns fn when what it read changes.
- Signals with computed and effectReactive signals: signal, computed, and effect, with automatic dependency tracking and no glitches.
Strings & formatting
- Escape HTMLTurn any value into text that's safe to put inside HTML, by replacing the five characters HTML treats specially.
- classNamesBuild a class attribute from strings, numbers, objects of flags, and nested arrays, skipping everything falsy.
- Format a listJoin names into a readable list like "Ada, Grace, and Alan", with "or" as an option and a limit that counts the rest.
- Build a query stringTurn an object into a URL query string, encoding every part, repeating keys for arrays, and skipping null and undefined.
- Format bytesTurn a size in bytes into a short label like 1.5 KB, picking the unit and rounding to a given number of decimals.
- SlugifyTurn a title into a URL slug: lowercase ASCII letters and digits joined by hyphens, with accents removed.
- Truncate at a word boundaryShorten text to a maximum length without cutting a word in half, ending with an ellipsis that counts toward the limit.
- Template rendererFill {{ path }} placeholders in a template with values from an object, following dotted paths and inserting values as plain text.
- camelCase, snake_case, and kebab-caseSplit text in any naming style into words, then join them again as camelCase, snake_case, or kebab-case.
- Parse a query stringTurn a URL query string into an object: decode every part, collect repeated keys into arrays, and keep __proto__ harmless.
- Format a numberFormat a number with a thousands separator and a fixed number of decimals, without Intl, rounding halves away from zero.
- Relative timeDescribe how long ago, or how far ahead, a date is: "just now", "3 minutes ago", or "in 2 days", without Intl.
- Compare versionsCompare two semver-style version strings, numbers first and then pre-release tags, for use as a sort comparator.
- Glob matchingCheck whether a file path matches a glob pattern with
?,*, and**wildcards, likesrc/**/*.test.js. - Highlight matchesWrap every case-insensitive match of a search query in <mark>, escaping the text so the result is safe HTML.
- Parse a CSV lineSplit one line of CSV into fields, handling quoted fields with commas and doubled quotes, and rejecting malformed quotes.
- Inline Markdown to HTMLConvert Markdown's code, bold, italic, and links into safe HTML: escape all text and allow only safe link URLs.
DOM
- Render a list from dataFill an empty list with one item per entry, safely, and render again when the data changes.
- Character counter for a textareaShow how many characters are left in a textarea as the user types, with a warning near the limit.
- getElementsByClassName by walking the treeFind every element inside a root that has all the given classes, walking the DOM tree yourself.
- Turn a DOM tree into JSONDescribe an element and everything inside it as plain { tag, attrs, children } data.
- Show password toggleLet users show and hide a password with a toggle button that keeps its label and reports its state with aria-pressed.
- Build DOM from a JSON specTurn nested { tag, attrs, children } data into real DOM nodes, with attributes, listeners, and safe text.
- Closest common ancestor of two nodesFind the deepest node that contains two given nodes, or null when they're in different trees.
- Next node in document orderFind the node that comes after a given one in a depth-first walk, without leaving a root.
- Event delegation helperHandle events for every matching element inside a container with one listener, including elements added later.
- Accordion with one open panelWire up accordion headers so one panel opens at a time, keeping aria-expanded and hidden in sync.
- Todo listWire a form, a list, and a counter into a working todo list with add, complete, and delete.
- Serialize a form to an objectRead a form's current values into a plain object, with booleans for lone checkboxes and arrays for multi-value fields.
- Star ratingTurn five stars into an accessible radio group: rate by clicking or with the arrow keys, with aria-checked and a roving tabindex.
- Sortable tableSort a table's rows when a column header is clicked, flipping the direction and keeping aria-sort on the sorted column.
- Checkbox tree with indeterminate parentsKeep a nested list of checkboxes in sync: a parent checks everything below it, and shows checked, unchecked, or mixed from its children.
- Tabs with arrow-key navigationBuild accessible tabs: aria-selected, a roving tabindex, panels shown by aria-controls, and arrow, Home, and End keys.
- Modal dialog with focus managementOpen a dialog with focus inside, keep Tab inside it, close it on Escape, and return focus where it was.
- Autocomplete comboboxBuild an accessible autocomplete: filter suggestions as the user types, move through them with aria-activedescendant, and pick one with Enter.
- Keyed list update that reuses nodesUpdate a list to match new data by key, reusing, moving, adding, and removing only the nodes that need it.