Functions, Scope & Object Model

Lexical Scope & Closures

JavaScript uses lexical scope: where a function is written determines which variables it can access. A closure is a function retaining access to variables from its outer lexical environment even after that outer function has returned.
  • Scope is based on code location, not caller
  • A closure captures variables, not snapshots
  • Closures are ordinary, not exotic
  • Closures can be a clean encapsulation tool
  • Closures can retain memory
Closure keeps the environment alive
The returned function keeps access to the `count` binding after `createCounter` returns.
Private state with a closure
function createCounter() {
  let count = 0

  return {
    next() {
      count += 1
      return count
    },
    reset() {
      count = 0
    },
  }
}

const counter = createCounter()
counter.next() // 1
counter.next() // 2
`count` is not reachable except through the returned methods.
Closure uses
UseExampleWatch out
EncapsulationFactory with private stateHidden state can still become hard to test
CallbacksEvent handler reads outer variableStale values in long-lived callbacks
MemoizationCache closed over by functionUnbounded memory growth
ConfigurationFunction factoryToo many layers can obscure flow
Sources
  • MDN JavaScript Guide and ReferenceFunctions; closures
  • You Don’t Know JS YetScope and Closures
  • Eloquent JavaScript, 4th EditionFunctions