ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

core-js 中 ECMAScript `globalThis` 的实现原理、入口与实战用法

core-js 中 ECMAScript `globalThis` 的实现原理、入口与实战用法 core-js 中 ECMAScriptglobalThis的实现原理、入口与实战用法【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js导读globalThis是 ECMAScript 2019ES10引入的标准全局对象统一访问方式它解决了浏览器window、Node.jsglobal、Web Workerself等不同宿主环境中全局对象名称不一致的痛点。在 core-js 仓库中globalThis既是一个被 polyfill 的标准特性也是整个库内部几乎所有模块获取全局对象的底层依赖。本文以 docs/web/docs/features/ecmascript/globalthis.md 为骨架结合 es.global-this 模块 与 internals/global-this 内部实现 的源码讲清globalThis的 polyfill 原理、各命名空间入口的用法以及如何在项目中选择合适的引入方式。一、globalThis是什么为什么需要 polyfill在globalThis成为标准之前JavaScript 代码要拿到全局对象需要写环境判断逻辑浏览器里是windowWeb Worker 里是selfNode.js 里是global非严格模式下还能用this兜底。core-js 文档给出的核心签名非常简洁let globalThis: GlobalThisValue;globalThis本质上就是那个始终指向全局对象的标准绑定它把跨宿主环境的差异收敛成一个名字。在支持的引擎中可以直接验证globalThis.Array Array; // true即全局对象上挂载着所有内置全局值globalThis.Array、globalThis.Math、globalThis.Promise等与直接引用等价。core-js 的单元测试也印证了这一点见 tests/unit-global/es.global-this.jsQUnit.test(globalThis, assert { assert.same(globalThis, Object(globalThis), is object); assert.same(globalThis.Math, Math, contains globals); });测试断言globalThis是一个对象Object(globalThis)返回自身且能通过它访问到Math等内置全局。对于老环境如 IE 11、旧版 Node引擎没有原生的globalThis此时就需要 core-js 提供的 polyfill。二、polyfill 实现原理从源码看核心机制1. 模块入口与是否强制注入的判断polyfill 的实际入口是 packages/core-js/modules/es.global-this.js代码非常短use strict; var $ require(../internals/export); var globalThis require(../internals/global-this); // globalThis object // https://tc39.es/ecma262/#sec-globalthis $({ global: true, forced: globalThis.globalThis ! globalThis }, { globalThis: globalThis });关键在第 7 行的forced条件globalThis.globalThis ! globalThis表示原生globalThis属性缺失即引擎尚未实现该标准特性此时强制注入 polyfill若引擎已原生支持globalThis该条件为假core-js 跳过注入直接使用原生实现。这体现了 core-js 默认的按需 polyfill策略特性可用且行为正确时绝不覆盖原生实现。$来自 internals/export.js它接收{ global: true }表示目标对象就是全局对象本身再通过defineBuiltIn等内部工具完成属性定义。2. 跨环境探测链internals/global-this.js的兜底逻辑真正负责找到全局对象的是 packages/core-js/internals/global-this.js它按优先级依次探测各个宿主环境提供的全局引用use strict; var check function (it) { return it it.Math Math it; }; module.exports // eslint-disable-next-line es/no-global-this -- safe check(typeof globalThis object globalThis) || check(typeof window object window) || // eslint-disable-next-line no-restricted-globals -- safe check(typeof self object self) || check(typeof global object global) || check(typeof this object this) || // eslint-disable-next-line no-new-func -- fallback (function () { return this; })() || Function(return this)();该实现的要点check(it)用it it.Math Math it做真伪校验候选对象必须存在且能访问到Math防止误选中与全局对象无关的同名变量例如某些环境中self可能是普通对象探测顺序为globalThis→window→self→global→ 非严格模式this→ 最后兜底Function(return this)()注释中引用了 core-js 历史上 issue #86 的讨论https://github.com/zloirock/core-js/issues/86#issuecomment-115759028说明这一多级探测正是为兼容各类老宿主而定型的方案。3. 该内部模块的另一层角色作为核心依赖被复用值得强调的是internals/global-this不仅是es.global-this这一个 polyfill 的数据来源它同时也是整个 core-js 库的内部基础设施——internals/export.js在定义任何全局特性时都通过var globalThis require(../internals/global-this)获取全局对象因此找全局对象这项工作在 core-js 中只实现一次、全库复用。此外es/global-this.js这个命名空间入口本身也是个再导出模块use strict; require(../modules/es.global-this); module.exports require(../internals/global-this);即加载 polyfill 模块之后再把内部探测到的全局对象作为模块导出值返回方便以const globalThis require(core-js/es/global-this)这种纯函数式方式使用。三、Entry points如何在 core-js 中按需引入原文档明确了globalThis的入口路径规则core-js(-pure)/es|stable|actual|full/global-this也就是说在core-js污染全局的完整版与core-js-pure不污染全局的纯净版两个包中global-this均有es、stable、actual、full四个命名空间入口对应不同激进程度的 polyfill 范围core-js/es/global-this只引入稳定版 ES 标准特性即globalThis所属的 ECMAScript 2019core-js/stable/global-this引入稳定版 ES 特性 Web 标准特性core-js/actual/global-this引入全部当前实际可用特性稳定 ES Web 标准 Stage 3 提案core-js/full/global-this引入全部特性包括早期 Stage 提案。对应文件已存在于仓库中packages/core-js/es/global-this.js、packages/core-js/stable/global-this.js、packages/core-js/actual/global-this.js、packages/core-js/full/global-this.js。用法上全局版直接引入副作用即可// 全局版注入 globalThis polyfill若缺失 import core-js/es/global-this; // 或 require(core-js/es/global-this);若使用不污染全局命名空间的core-js-pure则采用具名导入的方式拿到全局对象注意此时得到的是internals/global-this探测结果而非在全局上挂属性// 纯净版以模块值方式使用 import globalThis from core-js-pure/es/global-this; console.log(globalThis.Math Math); // true关于各命名空间的选择官方使用文档 docs/web/docs/usage.md 的Entry points一节建议默认优先使用/actual/命名空间因为它覆盖了所有实际可用特性又不包含仅供实验的早期提案。四、完整可运行示例与测试验证原文档给出的核心示例为globalThis.Array Array; // true这个断言在 polyfill 注入前后都应当成立引擎原生支持时成立被 polyfill 时成立因为 polyfill 暴露的就是真实的全局对象本身。在纯净版下对应示例来自 tests/unit-pure/es.global-this.jsimport globalThis from core-js-pure/es/global-this; QUnit.test(globalThis, assert { assert.same(globalThis, Object(globalThis), is object); assert.same(globalThis.Math, Math, contains globals); });可以看到全局版测试tests/unit-global/es.global-this.js直接使用全局globalThis而纯净版测试改为从core-js-pure/es/global-this导入——这正是两类入口在测试层面对应的两种消费方式。实际工程中推荐结合 Babelbabel/preset-envuseBuiltInscorejs选项或 swc 的coreJs配置按目标环境自动按需注入而不是手工在业务代码里散落 import具体配置方法同样可参考 docs/web/docs/usage.md。五、小结globalThis是 ECMAScript 2019 的标准全局对象访问方式core-js 通过 es.global-this 模块 在引擎缺失该属性时按需注入注入的实值来自 internals/global-this.js 的多级环境探测该内部模块同时是全库获取全局对象的基础设施按需引入请遵循core-js(-pure)/es|stable|actual|full/global-this入口规则默认推荐/actual/命名空间需要不污染全局命名空间时改用core-js-pure的具名导入方式测试用例见 tests/unit-pure/es.global-this.js。【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表