CodeOath
← All posts
JavaScript75 min total · 15 parts

JavaScript Core Concepts: Scope, Closures, `this`, and the Event Loop

Contents — Part 15 of 15: Common Mistakes Worth Remembering
Part 15 of 15 · ~1 min

Common Mistakes Worth Remembering

  • Using var inside a loop with an async callback and expecting each callback to see "its own" loop variable — only let creates a fresh binding per iteration.
  • Passing an object method as a bare callback (element.addEventListener("click", obj.method)) and losing its this binding — needs .bind(obj) or an arrow-function wrapper.
  • Forgetting that setTimeout(fn, 0) still runs after all synchronous code and all pending microtasks, not immediately.
  • Awaiting two independent async calls sequentially instead of running them concurrently with Promise.all, silently doubling wait time.
  • Calling an async function without await or .catch() and having a rejection go completely unhandled.
  • Confusing Promise.all (fails fast on the first rejection) with Promise.allSettled (always resolves, reporting each outcome) and using the wrong one for a batch of independent operations.
  • Blocking the single thread with a long synchronous computation and wondering why the UI froze and no timers fired.
  • Assuming closures capture a variable's value at creation time rather than a live reference to the variable itself.

These four mechanisms — scope, closures, this, and the event loop — compound constantly in real code: a setTimeout callback inside a loop needs both closures (which i does it capture?) and the event loop (when does it actually run?); an event handler defined as an arrow function inside a class method needs both closures and this binding to behave correctly. The stale-closure bug covered in React Fundamentals is exactly this same closure mechanism showing up inside useEffect. See TypeScript Fundamentals for how a type system layers on top of this same runtime, and the array/object methods cheat sheet for the data-manipulation side of everyday JavaScript.

Try every one of these scenarios as runnable code in the code lab.