JavaScript Module Scope
Each JavaScript module has its own lexical scope, so declarations inside one module are not automatically available as globals or as local variables in another module. Modules communicate explicitly through `export` and `import`.
A JavaScript file loaded as a module has its own top-level lexical environment. Variables, functions, classes, and constants declared at the module's top level belong to that module rather than becoming properties of the global object.
This means two modules can use the same identifier without accidentally sharing the same binding. For example, both modules can declare `const value` and each declaration remains local to its own module.
To make a declaration available to another module, explicitly export it with `export`. The receiving module then imports the binding with `import`. This creates a clear dependency relationship between modules.
Module scope is different from ordinary function scope because the module boundary itself establishes lexical isolation. Top-level `let`, `const`, and `class` declarations are not global variables merely because they appear at the top level of the file.
In browser applications, module scripts are enabled with `<script type="module">`. Modules are also commonly used by build tools and JavaScript runtimes that support ECMAScript modules.
Key points
- Top-level declarations in a module belong to that module's lexical scope.
- Module declarations do not automatically become global variables.
- Use `export` to expose a binding and `import` to consume it elsewhere.
- Different modules can have independent bindings with the same identifier name.
- Module scope provides isolation and makes dependencies explicit.
Interview questions
What happens when two modules both declare `const config`?
Each module has its own lexical environment, so the two `config` declarations are independent bindings. Their names do not conflict merely because the modules are part of the same application. A module can use the other module's configuration only if that value is exported and imported. The imported binding is then resolved through the module dependency relationship rather than through the global scope.
What is module scope in JavaScript?
Module scope is the lexical scope created for an individual JavaScript module. Top-level declarations in that module are not automatically placed in the global scope. Other modules access a declaration only when the module exposes it through its export interface. This keeps dependencies explicit and prevents unrelated modules from accidentally sharing names.
Do top-level `let` and `const` declarations in a module become global variables?
No. In an ECMAScript module, top-level `let` and `const` declarations are scoped to that module. They do not automatically become properties of the global object. If another module needs the value, the module should export it and the other module should import it.
Why is module scope useful in frontend applications?
Module scope prevents implementation details from leaking into unrelated parts of an application. It also allows different modules to reuse common identifier names without collisions. Explicit `import` and `export` statements make dependencies visible in the source code. This improves organization and reduces accidental coupling between components.
How would you explain module scope to a developer debugging an undefined variable?
I would first check whether the variable belongs to the same module or is being referenced across a module boundary. A declaration that exists in another module is not automatically visible here; it must be part of that module's exported interface and imported correctly. I would then verify the export form, import syntax, and module path. This approach distinguishes a scope problem from a module-resolution or naming problem.