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
ES modules are strict, have
undefinedas top-levelthis, and load in phases: parse, link, then evaluate dependencies first. Imports are hoisted, live and read-only. - 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
In ESM cycles, function declarations are usable before their module runs, but
let,constandclassexports throw a TDZ ReferenceError. - 4
An iterator is an object with
next();return()is called on early exit (break, throw, destructuring that stops early), which is how generators runfinally. - 5
In a generator, each
next(arg)answers the previousyield, so the first argument is discarded.yield*forwards values and evaluates to the delegate's return value. - 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
??=,||=and&&=short-circuit the whole assignment, so setters do not run when no assignment is needed.
Common traps
A global regex keeps
lastIndexbetweentest()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.
Read the source
Test yourself on Modules, Iterators and Metaprogramming
Ten questions, with the answer and explanation after each one.