7 min read

Eye Training · Functions, this and Closures

this is decided by how a function is called, not where it's written. A closure keeps whatever it can see, for as long as it lives.

Part 2 · Surface 22. Bug counts are hidden and some snippets are clean. See Start Here for how to use these drills.


J · The basics

Bug hunt
J · Click counter
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Stopwatch
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Line totals
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Map to ids
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Health route
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Add to a list
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

M · Three years in, these should jump out

Bug hunt
M · Search box
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Format prices
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Destructured service
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Connect once
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Toggle button
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Counter factory
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

S · Where seniors stand out

Bug hunt
S · Export summaries
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min
Bug hunt
S · Deep clone
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min

What your eye checks

Whenever a function is passed around, stored, or defined inside another, ask:

  1. How will it be called? Passed as a callback (addEventListener, map, setTimeout) or destructured, a method loses its object.
  2. Arrow or function? Arrows take this from where they're written: right for callbacks inside methods, wrong as object methods.
  3. Does the arrow body return? { } needs return; an object literal needs ({ }).
  4. Is it defined before it's used? const and let have a temporal dead zone; function declarations are hoisted.
  5. Is a stateful function created once or on every call? Debounced, throttled and memoized functions must be created once.
  6. What does the closure capture, and how long does it live? A long-lived callback keeps every variable it refers to.
  7. What happens on the second call? once, memoize and init helpers must return the stored result.
  8. Does recursion have a way out? Base cases, depth limits, cycles.

Tells

You seeAsk
addEventListener('…', obj.method)What is this?
method: () => { this… } in an objectArrow as a method?
.map((x) => {Is there a return?
=> { key: value }Block or object?
A route using a handler defined below itconst or function?
debounce(fn, ms)(…) inside a handlerCreated on every call?
.map(this.method)Detached method?
const { method } = serviceDetached method?
this. inside an arrow inside a classWhich this?
A closure stored in a long-lived MapWhat does it keep alive?
A hand-written deep cloneDates? Cycles?

Go deeper