JavaScript is wide. You can "know JS" and still burn time on the same stuff: - Which Promise helper do I want here? - Why is `this` undefined in my callback? - Why did my effect run twice in dev? - Why did my spread copy still share nested objects?
This is not a tutorial. It's recall practice. You type patterns from memory, the scheduler tracks what you forget, and weak spots come back until they stick. Async, modules, DOM, hooks, TypeScript. The stuff you actually ship.
Popular topics include JavaScript Async/Await Practice, JavaScript Functions Practice, JavaScript Loops Practice.
Built for JavaScript Learners
- Frontend and full-stack devs who write JS regularly.
- Prepping for JavaScript or React interviews.
- Backend devs picking up frontend or Node.
- Coming back to JS after a few years away.
- Know when to use Promise.all vs allSettled vs race.
- Pick declaration vs arrow vs expression without thinking.
- Stop confusing for...of and for...in.
- Stop accidentally mutating objects when you spread them.
- Get imports, exports, and TDZ right.
- Use the DOM without XSS holes or layout thrashing.
- Write useEffect without stale closures or infinite loops.
- Use TypeScript to catch bugs, not to silence the compiler.
- Pass class methods as callbacks without losing `this`.
- Handle async errors without swallowing or leaking them.
- Know why `"👍".length` is 2, not 1.
Practice by Topic
Pick a concept and train recall with small, focused reps.
JavaScript Async/Await Practice
Stop mixing up Promise.all vs allSettled and forgetting that forEach won't await.
Show 3 gotchasHide gotchas
asyncfunctions always return PromisesPromise.allfails fast;allSettledwaits for everythingforEach()doesn'tawaitasync callbacks — usefor...ofinstead
JavaScript Functions Practice
Know when arrow vs declaration matters — this binding, hoisting, and closure capture.
Show 3 gotchasHide gotchas
- Arrow functions capture outer
this - Function declarations hoist;
let/constexpressions have TDZ - Closures capture by reference, not value
JavaScript Loops Practice
Stop confusing for...in (keys) vs for...of (values) and reduce on empty arrays.
Show 3 gotchasHide gotchas
for...ingives you keys;for...ofgives you valuesforEachcan'tbreakand doesn'tawaitcallbacksreducethrows on empty arrays without an initial value
JavaScript Collections Practice
Know when spread silently shallow-copies and when includes() finds NaN but === doesn't.
Show 3 gotchasHide gotchas
- Spread is a shallow copy
includes()is like===, butNaNmatchesNaNObject.keys()returns strings, even for numeric keys
JavaScript Modules & Scope Practice
Get TDZ, const mutation, and import hoisting right without trial and error.
Show 3 gotchasHide gotchas
let/const/classthrow if used before declaration (TDZ)- Static
importhoists; dynamicimport()does not conststops reassignment, not mutation
JavaScript DOM Manipulation Practice
Avoid XSS from innerHTML and layout thrashing from interleaved reads and writes.
Show 3 gotchasHide gotchas
querySelectorcan returnnullinnerHTMLis an XSS risk;textContentis not- Mixing reads and writes causes layout thrashing
JavaScript React Hooks Practice
Fix stale closures, infinite re-renders, and Strict Mode double-fire in useEffect.
Show 3 gotchasHide gotchas
- Strict Mode runs an extra setup+cleanup cycle in dev
- Missing deps cause stale closures
- Effects sync with external systems, not internal state
TypeScript Practice
Use satisfies over as, unknown over any, and generics to keep real type info.
Show 3 gotchasHide gotchas
satisfieschecks shape without wideningunknownforces narrowing;anydisables it- Generics keep type info that
anyloses
JavaScript Classes Practice
Stop losing this when passing methods as callbacks and forgetting super() before this.
Show 3 gotchasHide gotchas
- Passing a method as callback loses
this - Private
#fields cannot be accessed dynamically super()must come beforethis
JavaScript Error Handling Practice
Throw Error objects (not strings), handle unhandled rejections, and know why return await matters in try/catch.
Show 3 gotchasHide gotchas
- Throw
Errorobjects, not strings - Unhandled rejections can terminate the process
return awaitmatters insidetry/catch
JavaScript String Methods Practice
Know why "👍".length is 2, why replace() hits only the first match by default, and when slice beats substring.
Show 3 gotchasHide gotchas
.lengthcounts UTF-16 code units, not charactersreplace()only hits the first match by defaultslice()supports negative indices;substring()does not
JavaScript Cheat Sheets
Copy-ready syntax references for quick lookup
Sample Exercises
Create a Promise that resolves to "Success".
new Promise(resolve => resolve("Success"))Define a function `greet` taking `name` as an argument.
function greet(name) {
}
Why this works
You forget things fastest right after learning them. Spaced repetition quizzes you before you forget, so patterns stick instead of fading.
FAQ
No. This is practice for people who already know JavaScript but want faster recall.
Working devs, people prepping for interviews, anyone who keeps googling the same syntax.
Yes. Both have their own sections.
No. Promises, modules, error handling, and strings apply to Node too.
A week or two of daily practice. You will google less.
No. LeetCode is algorithms. This is syntax recall.
Yes. They are patterns you would write at work, not trivia.
Yes. ES6+ through current: async/await, modules, hooks, TypeScript.
No. Those topics are optional. Start with core JS.
Yes. If you can write a function and use arrays, you are ready. This is not a first course.
10 minutes a day. Consistency matters more than long sessions.
Imports, exports, TDZ, let vs const vs var, live bindings.