Scope in ES Modules vs Scripts in JavaScript
ES modules change how top-level scope works. Here is how module scope differs from classic script scope.
Scope in ES Modules vs Scripts in JavaScript
ES modules (import/export) change how top-level scope works compared to classic scripts. This affects globals, this, and variable visibility.
Classic Script Scope
In a classic <script> tag or a CommonJS file:
- Top-level
varbecomes a property ofwindow(browsers). - Top-level
let/constlive in a global lexical environment (not onwindow). - Top-level
thisis the global object (windowin browsers). - Multiple scripts share the same global scope.
// script.js (classic) var x = 5; console.log(window.x); // 5 console.log(this === window); // true `` ### ES Module Scope In an ES module (`<script type="module">` or a file with `import`/`export`): - Top-level `var`, `let`, `const`, and `class` are **module-scoped**, not global. - They are only accessible outside the module if explicitly exported. - Top-level `this` is `undefined`. - Each module has its own top-level scope; modules do not share globals. ```js // module.js (ES module) var x = 5; console.log(window.x); // undefined (x is module-scoped) console.log(this); // undefined export const y = 10; // y is accessible to importers `` ### Key Differences | Feature | Classic Script | ES Module | |---|---|---| | Top-level `var` | Property of `window` | Module-scoped | | Top-level `let`/`const` | Global lexical env | Module-scoped | | Top-level `this` | `window` | `undefined` | | Strict mode | Optional | Automatic | | Shared globals | Yes (across scripts) | No (each module is isolated) | ### Why This Matters - **No global pollution**: modules keep their top-level variables private by default. - **Safer `this`**: `undefined` prevents accidental global mutation. - **Explicit exports**: you must opt-in to share variables. - **Strict mode by default**: catches more bugs. ### Practical Implications - If you need the global object in a module, use `globalThis`. - If you need to share a value across modules, `export` it. - If you need a truly global variable (rare), attach to `globalThis`. ### The Takeaway ES modules have their own top-level scope. Top-level variables are module-scoped, not global. Top-level `this` is `undefined`. Strict mode is automatic. Use `export` to share values, `globalThis` for the global object, and prefer modules over classic scripts.
In classic scripts, top-level var becomes a property of window and this is the global object. In ES modules, top-level variables are module-scoped (not global), this is undefined, and strict mode is automatic.
No. In ES modules, top-level var, let, const, and class are module-scoped. They are not properties of window and are only accessible outside the module if explicitly exported.
undefined. In classic scripts, top-level this is the global object (window). In ES modules, it is undefined to prevent accidental global mutation. Use globalThis if you need the global object.
Yes. Any file with import or export is automatically in strict mode. You do not need 'use strict'. This catches more bugs like accidental globals and duplicate parameter names.
Export it from one module and import it in another. Top-level variables in a module are private by default. Only explicitly exported values are accessible to importers.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

