Study notes · 10% of the exam

Modules, Iterators and Metaprogramming

Know how ES modules load and link, how iterators and generators really step, and how symbols, Proxy and Reflect hook into the language. Interviews probe the edge cases: cycles, live bindings, next(arg) sequencing and Proxy invariants.

Key points

  1. 1

    ES modules are strict, have undefined as top-level this, and load in phases: parse, link, then evaluate dependencies first. Imports are hoisted, live and read-only.

  2. 2

    CommonJS exports are a plain object filled in as the file runs: destructuring copies values, and a require cycle returns a half-filled exports.

  3. 3

    In ESM cycles, function declarations are usable before their module runs, but let, const and class exports throw a TDZ ReferenceError.

  4. 4

    An iterator is an object with next(); return() is called on early exit (break, throw, destructuring that stops early), which is how generators run finally.

  5. 5

    In a generator, each next(arg) answers the previous yield, so the first argument is discarded. yield* forwards values and evaluates to the delegate's return value.

  6. 6

    Forward Proxy traps with Reflect.*(target, key, receiver) to keep getters and inheritance correct. Invariants make traps throw when they misreport locked properties.

  7. 7

    ??=, ||= and &&= short-circuit the whole assignment, so setters do not run when no assignment is needed.

Common traps

  • A global regex keeps lastIndex between test() calls, so the same input can alternate between true and false.

  • Private fields and built-ins with internal slots (Map, Set, Date) break when a method is called with a Proxy as this.

  • import() resolves to the module namespace: the default export is .default, not the resolved value itself.

Test yourself on Modules, Iterators and Metaprogramming

Ten questions, with the answer and explanation after each one.