为什么理解全局 this 是理解 JavaScript 环境的基础
JavaScript 在不同的运行环境中执行:浏览器、Node.js、Web Worker、Deno 等。每个环境都有自己的"全局对象",提供语言核心功能和宿主 API。
理解全局对象的演进历史和 globalThis 的统一方案,是理解 JavaScript 多端运行能力的基础。
一、全局对象的历史
1.1 浏览器中的 window
在浏览器中,全局对象是 window:
// 浏览器环境
console.log(window === this); // true
console.log(window === globalThis); // true
// 在全局作用域声明的变量成为 window 的属性
var globalVar = 'hello';
console.log(window.globalVar); // 'hello'
// let/const 不挂载到 window
let localVar = 'world';
console.log(window.localVar); // undefined
1.2 Node.js 中的 global
Node.js 使用 global 作为全局对象:
// Node.js 环境
console.log(global === globalThis); // true
// 全局变量不是 global 的属性(除非显式赋值)
global.myVar = 'test';
console.log(global.myVar); // 'test'
1.3 Web Worker 中的 self
Web Worker 中没有 window,使用 self:
// Web Worker 环境
console.log(self === globalThis); // true
console.log(self.toString()); // '[object DedicatedWorkerGlobalScope]'
二、globalThis 的统一方案
2.1 问题
不同环境使用不同的全局对象名称:
// 传统做法:环境检测
const getGlobal = () => {
if (typeof window !== 'undefined') return window;
if (typeof global !== 'undefined') return global;
if (typeof self !== 'undefined') return self;
throw new Error('Cannot find global object');
};
// 非常繁琐且容易出错
2.2 ES2020 的解决方案
ES2020 引入了 globalThis,提供统一访问全局对象的方式:
// 所有环境都支持
console.log(globalThis.Array === Array); // true
console.log(globalThis.Object === Object); // true
console.log(globalThis.JSON === JSON); // true
2.3 globalThis 的 polyfill
ES2020 之前的浏览器需要 polyfill:
(function() {
if (typeof globalThis === 'undefined') {
Object.defineProperty(Object.prototype, '__magic__', {
get: function() {
return this;
},
configurable: true
});
__magic__.globalThis = __magic__;
delete Object.prototype.__magic__;
}
})();
三、全局对象的特性
3.1 全局对象的属性
全局对象上有很多重要的属性和方法:
// 核心对象(标准库)
globalThis.Object;
globalThis.Array;
globalThis.Function;
globalThis.String;
globalThis.Number;
globalThis.Boolean;
globalThis.Symbol;
globalThis.Error;
globalThis.JSON;
globalThis.Math;
globalThis.Date;
// 核心函数
globalThis.parseInt;
globalThis.parseFloat;
globalThis.isNaN;
globalThis.isFinite;
globalThis.eval;
globalThis.encodeURI;
globalThis.decodeURI;
// 构造函数
globalThis.RegExp;
globalThis.Map;
globalThis.Set;
globalThis.WeakMap;
globalThis.WeakSet;
globalThis.Promise;
globalThis.Proxy;
3.2 宿主环境添加的属性
// 浏览器环境
globalThis.alert;
globalThis.fetch;
globalThis.console;
globalThis.document;
globalThis.navigator;
globalThis.location;
// Node.js 环境
globalThis.process;
globalThis.require;
globalThis.module;
globalThis.exports;
globalThis.__dirname;
globalThis.__filename;
四、全局对象的访问模式
4.1 在任何地方访问全局对象
// 推荐方式
const g = typeof globalThis !== 'undefined'
? globalThis
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: {};
// 或者使用 Function
const getGlobal = (new Function('return this'))();
4.2 模块中访问全局对象
// ES Module 中
import url from 'url';
// CommonJS 中
const url = require('url');
// 动态代码中
const globals = new Function('return this')();
五、面试高频考点
考点 1:不同环境的全局对象
- 浏览器:window
- Node.js:global
- Web Worker:self
- ES2020+:globalThis
考点 2:var 声明与全局对象
用 var 在全局作用域声明的变量会成为全局对象(window/global)的属性,而 let/const 不会。
考点 3:globalThis 的意义
统一不同 JavaScript 运行环境的全局对象访问方式,解决了历史遗留的兼容性问题。