用 globalThis 来访问全局变量

用 globalThis 来访问全局变量JavaScript 可以在不同的环境下执行,常见的有浏览器,Web Worker, Node, Deno 等等。在不同的环境下,访问全局变量的方法不一样。比如,在浏览器上,就有 window, se

JavaScript 可以在不同的环境下执行,常见的有浏览器,Web Worker, Node, Deno 等等。在不同的环境下,访问全局变量的方法不一样。比如,在浏览器上,就有 window, self, frames 等方式。在 Web Worker 里是 self。在 Node 里是 global。

例子:

/* 浏览器环境 */
window === self       // true
window === frames     // true

// 最顶层的窗口
window === parent     // true
window === window.top // true

window.msg = 'hello,world' // ok
console.log(msg).          // hello,world

同样的代码,在 Web Worker 环境,或 Node 环境下运行就会报错。

/* Node */
window.msg = 'hello,world' // Uncaught ReferenceError: window is not defined
console.log(msg)           // Uncaught ReferenceError: msg is not defined

global.msg = 'hello,world' // ok
console.log(msg)           // hello,world

globalThis 提供了一种统一的访问全局变量的方案,比如在浏览器环境,它会指向 window,在 Node 环境,它会指向 global。

/* 在绝大多数 JavaScript 运行环境下都能运行 */
globalThis.msg = 'hello,world'
console.log(msg);

例如在一个 SSR 项目里,如果因为要访问全局变量而使用 window,很可能会导致在服务端渲染的时候报错。这时候,将 window 改成 globalThis 或许就能解决。

兼容性

除了 IE 以外,主流的 JavaScript 运行环境都已经支持 globalThis 。如果想要兼容 IE,可以使用开源的 polyfill 包 github.com/es-shims/gl…

历史方案

globalThis 还没广泛实现之前,常见的方案是使用类似这样的补丁:

const getGlobalThis = () => {
	if (typeof globalThis !== 'undefined') return globalThis;
	if (typeof self !== 'undefined') return self;
	if (typeof window !== 'undefined') return window;
	if (typeof global !== 'undefined') return global;
	if (typeof this !== 'undefined') return this;
	throw new Error('Unable to locate global `this`');
};
var globalThis = getGlobalThis();

来获取当前环境的全局变量。

但是这个补丁并不完美,因为依赖到 this 在非严格模式的函数里,会返回全局对象的特点。 在严格模式下就会失效(严格模式下,函数返回的 thisundefined)。

另一个更完善,但是也更奇怪的方案:

(function() {
	if (typeof globalThis === 'object') return;
	Object.prototype.__defineGetter__('__magic__', function() {
		return this;
	});
	__magic__.globalThis = __magic__; // lolwat
	delete Object.prototype.__magic__;
}());

// Your code can use `globalThis` now.
console.log(globalThis);

这段奇怪的代码,为什么比上一个方案更完善,为什么这样子写,具体的解释可以看参考资料里的链接。

总结

目前 globalThis 已经进入提议进程的 Stage 4,意味着它已经准备好在接下来的 ECMAScript 版本中发布。所以如果不需要兼容 IE,可以放心使用。

参考资料

developer.mozilla.org/en-US/docs/…

tc39.es/ecma262/mul…

mathiasbynens.be/notes/globa…

今天的文章用 globalThis 来访问全局变量分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23418.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注