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.element.addEventListener("click", obj.method)) and losing its this binding — needs .bind(obj) or an arrow-function wrapper.setTimeout(fn, 0) still runs after all synchronous code and all pending microtasks, not immediately.Promise.all, silently doubling wait time.async function without await or .catch() and having a rejection go completely unhandled.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.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.