阿里云主机折上折
  • 微信号
Current Site:Index > The relationship changes between global variables and the window object

The relationship changes between global variables and the window object

Author:Chuan Chen 阅读数:5357人阅读 分类: JavaScript

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:

  1. Script Scope: Traditional <script> tags share the same global object.
  2. Module Scope: Each module has its own top-level scope.
  3. 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:

  1. Feature detection should use globalThis:
// Old way
if (window.Promise) {...}

// New way
if (globalThis.Promise) {...}
  1. Polyfill loading must consider scope:
// Traditional polyfills affect window
window.Promise = MyPromisePolyfill;

// Modular polyfills only affect the current module
import Promise from 'es6-promise';
  1. 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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.