js window 和 globalThis 区别
globalThis 是 ES2020 规定的跨环境全局对象引用,window 是浏览器专有全局对象;二者在浏览器主线程严格相等,在 Node.js 和 Web Worker 中 window 不存在,因此跨环境代码应优先使用 global
结论:globalThis 是 ES2020 规定的“跨环境全局对象引用”,window 是浏览器专有的全局对象;在浏览器主线程里 globalThis === window 返回 true,而在 Node.js、Web Worker 里 window 直接不存在。
window 和 globalThis 到底是什么关系?
结论:在浏览器主线程中,globalThis、window、self、frames 指向同一个对象,严格相等。
可以复制到 Console 中验证:
globalThis === window // true
globalThis === self // true
window.window === window // true,全局对象自引用
globalThis.globalThis === globalThis // true
在浏览器中,全局对象就是 Window 接口的实例。globalThis 只是 ECMAScript 规范提供的一个“指向当前全局对象的标准化别名”,并没有任何额外能力。因此,只要 document、location、localStorage 挂在全局对象上,globalThis.document 也同样能拿到。
window 和 globalThis 的核心区别有哪些?
结论:区别不在“能不能用”,而在“谁定义、在哪有、保证什么”。
- 规范归属不同:
window由 HTML Standard 定义,属于 Web 平台;globalThis由 ECMAScript 2020 定义,属于语言层。前者受浏览器约束,后者受 JS 引擎约束。 - 存在范围不同:浏览器窗口、iframe 中有
window;Web Worker 中只有self,window是undefined;Node.js 中全局对象是global,同样没有window。 - API 语义不同:
window携带 BOM 与窗口特有成员,如window.open()、window.parent、window.top、window.name、window.innerWidth。globalThis只保证“这是全局对象”,不保证上面有任何浏览器 API。 - 检测稳定性不同:直接写
window === undefined在 Node 中会抛ReferenceError,必须用typeof window !== 'undefined'。而typeof globalThis !== 'undefined'在所有符合标准的引擎中都是安全的。
跨环境代码为什么优先用 globalThis?
结论:要让同一份代码跑在浏览器、Worker、Node 三端,只用 globalThis 访问全局对象是最省事的写法。
典型场景是库作者遇到的老问题:以前写 polyfill 要写一长串兼容判断:
// 旧写法
var g = typeof window !== 'undefined' ? window
: typeof global !== 'undefined' ? global
: typeof self !== 'undefined' ? self
: this;
// 现在的写法
const g = globalThis;
兼容性数据:globalThis 从 Chrome 71、Firefox 65、Safari 12.1、Node.js 12.0 起原生支持,IE11 完全不支持。面向 IE 或老安卓 WebView 的项目,仍需引入 core-js 提供的 polyfill,其原理是在检测到缺失时把全局对象赋给 globalThis 这个名字。
var 声明的变量和 globalThis 是什么关系?
结论:全局 var 和 function 声明会成为全局对象的属性,let、const、class 声明不会。
var a = 1;
let b = 2;
globalThis.a // 1
globalThis.b // undefined
因此,用 globalThis.x 检测“某个全局变量是否存在”时,只能检测到 var 声明的变量和直接挂到全局对象上的属性,检测不到 let、const 声明的变量。在模块(type="module")中,顶层 var 也不会挂到全局对象上,因为模块有自己的作用域。
用 globalThis 容易踩哪些坑?
结论:把 globalThis 当成“一定有 DOM 或一定有 window”的同义词,是最常见的错误。
- SSR 中误判环境。在 Next.js、Nuxt 的服务端渲染阶段,
globalThis存在,但globalThis.document是undefined。要判断是否为浏览器环境,应该写typeof window !== 'undefined',而不是判断globalThis是否存在。 - 跨 realm 的 instanceof 失效。在 iframe 里,
iframe.contentWindow是另一个全局对象。用iframe.contentWindow.Array !== Array可以验证:如果父窗口的代码对 iframe 内数组做instanceof Array,会返回false。 - 全局污染难以排查。
globalThis.myLib = {}与window.myLib = {}效果一样,都会造成全局命名污染,多人协作时容易互相覆盖。除非明确要暴露接口,否则优先使用模块导出。 - 不要为了“看起来现代”而替换 window。访问
window.location.href、调用window.open()这类窗口专属能力时,应继续使用window,因为这样能表明依赖的是浏览器环境,语义更清晰。
实际项目里该怎么选?
结论:一句话规则——通用取全局对象用 globalThis,浏览器专属操作用 window,环境判断用 typeof window。
- 写 polyfill、工具库、同构 SDK:用
globalThis。 - 做窗口跳转、iframe 通信、读取视口尺寸:用
window。 - 写 SSR 分支逻辑:
if (typeof window !== 'undefined')。 - 适配老旧浏览器:先确认构建目标,必要时加载
globalThispolyfill。
这类前端细节讨论,社区里一般发在技术交流 → 前端开发版块(子分类 HTML、JS、CSS、Vue、React),有具体报错可以直接贴代码提问。
小结:globalThis 是语言层提供的跨环境全局对象入口,window 是 HTML 规范定义的浏览器全局对象;两者在浏览器中指向同一实体,但规范来源、可用边界和语义保证完全不同。区分清楚这三层(语言层、平台层、环境检测层),代码在浏览器、Worker、Node 之间迁移时就不会因为一个 window is not defined 卡住。
转载请注明出处,版权归原作者所有。