The relationship changes between global variables and the window object
ECMAScript 6 (ES6) introduced significant adjustments to the handling of global variables, particularly altering their relationship with the window
object. These changes affect variable declarations, scoping, and the property-binding mechanism of the global object, requiring developers to reinterpret the traditional relationship between global variables and the browser environment.
Traditional Relationship Between Global Variables and the window
Object
In ES5 and earlier versions, global variables declared with var
automatically became properties of the window
object. This design originated from JavaScript's implementation in browser environments:
var globalVar = 'ES5 variable';
console.log(window.globalVar); // Output: 'ES5 variable'
Function declarations were also bound to the window
object:
function globalFunc() {
return 'ES5 function';
}
console.log(window.globalFunc()); // Output: 'ES5 function'
This mechanism led to global namespace pollution, as all script files shared the same window
object for their global variables.
Changes in Variable Declaration in ES6
ES6 introduced let
, const
, and module mechanisms, fundamentally altering the behavior of global variables:
Global Declarations with let
and const
Variables declared with let
or const
in the global scope do not automatically become properties of the window
object:
let es6Let = 'block scoped';
const es6Const = 42;
console.log(window.es6Let); // undefined
console.log(window.es6Const); // undefined
These variables reside in the global lexical environment rather than the global object and can be accessed via globalThis
in any context:
console.log(globalThis.es6Let); // Still undefined, as they are not bound to the global object
Impact of Module Scope
In ES6 modules (using <script type="module">
), top-level variable declarations do not become properties of the global object:
<script type="module">
let moduleScoped = 'not global';
console.log(window.moduleScoped); // undefined
</script>
New Way to Access the Global Object
ES2020 standardized globalThis
as a cross-environment way to access the global object:
// Browser environment
console.log(globalThis === window); // true
// Node.js environment
console.log(globalThis === global); // true
// Universal access
globalThis.standardProperty = 'universal';
Global Variable Isolation Mechanisms
ES6 implements global isolation through the following mechanisms:
- Script Scope: Traditional
<script>
tags share the same global object. - Module Scope: Each module has its own top-level scope.
- Global Lexical Environment: Global variables declared with
let/const
reside in a separate environment.
Example comparison:
// Traditional script
<script>
var shared = 'visible';
</script>
<script>
console.log(window.shared); // 'visible'
</script>
// Module script
<script type="module">
let isolated = 'hidden';
</script>
<script type="module">
console.log(isolated); // ReferenceError
</script>
Changes to Built-in Objects
ES6 relocated some built-in objects from the global object to other locations:
// ES5
console.log(window.Array === Array); // true
// ES6 new built-ins
console.log(window.Symbol); // Exists
console.log(window.WeakMap); // Exists
console.log(window.Promise); // Exists
// But some APIs are no longer attached to window
console.log(window.globalThis); // Available in supported environments
Practical Implications and Migration Considerations
When migrating existing code, note the following:
- Feature detection should use
globalThis
:
// Old way
if (window.Promise) {...}
// New way
if (globalThis.Promise) {...}
- Polyfill loading must consider scope:
// Traditional polyfills affect window
window.Promise = MyPromisePolyfill;
// Modular polyfills only affect the current module
import Promise from 'es6-promise';
- Cross-window communication requires explicit references:
// Parent window accessing iframe
const iframeWindow = document.getElementById('frame').contentWindow;
iframeWindow.postMessage(/*...*/);
// No longer accessible via implicit window chain
Enhanced Behavior in Strict Mode
ES6 modules automatically enforce strict mode, further preventing global variable leaks:
// In modules
undeclaredVar = 'leak'; // Throws ReferenceError
// In non-module scripts
undeclaredVar = 'leak'; // Creates window.undeclaredVar
Changes in Dynamic Code Execution
The behavior of code executed via eval
has also changed:
// Direct eval
function testEval() {
eval('var evalVar = "leaked"');
console.log(evalVar); // 'leaked' (non-strict mode)
console.log(window.evalVar); // undefined (in ES6 environments)
}
// Indirect eval
const indirectEval = eval;
indirectEval('var indirectVar = 123');
console.log(window.indirectVar); // 123 (still pollutes the global scope)
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:暂时性死区(TDZ)概念
下一篇:块级作用域在循环中的应用