原文:https:⭐️//ilikekillnerds.com/2023/02/why-you-should-be-using-globalthis-instead-of-window-in-your-javascript-code/
我讨厌成为那些总是发博客说 “不要用X” 或者 “为什么你应该使用Y来代替” 的人,但最近在我修改很久之前写的代码时发现写一篇关于“为什么应该用globalthis作为代替”的博客是很有必要的。并不是说现在在用的window
是错误的(因为在浏览器环境globalthis和window是等价的),然而通过使用globalthis
可以给自己节省很多麻烦,尤其是在单元测试中!
科普下,globalthis
是由 ECMAScript 2020 引入全新的全局变量。无论是在浏览器、node
服务或在web worker
等其他环境中globalthis
提供了访问全局变量的方法。使用globalthis
替代 window
或global
的最大好处是可以保障你的代码更具一致性和前瞻性;
以下是一些globalthis在不同环境中的例子:
在浏览器环境中
globalThis
和window
对象等价,举个栗子:
console.log(globalThis === window); // true
console.log(globalThis.location.href); // same as window.location.href
通过使用globalThis
进行替换后可保证在任何浏览器中都可正常工作。
在nodejs环境中
globalThis和全局对象等价,举个栗子:
console.log(globalThis === global); // true
console.log(globalThis.setTimeout === global.setTimeout); // true
通过使用globalThis
替换可保证在任何node环境中都可正常工作。
在web worker环境中
globalThis与当前worker实例等价,举个栗子:
console.log(globalThis === self); // true
console.log(globalThis.postMessage === self.postMessage); // true
通过使用globalThis替换self可以保证在任何web workder环境中都可正常工作。
在单元测试中
使用globalThis的最大好处就是可以使你的单元测试变得更容易,尤其是你需要模拟想window或global之类的全局对象。
比如我们有个函数,其依赖于window对象
function showMessage(message) {
window.alert(message);
}
为了测试这个函数,你可能需要模拟window对象。然而模拟window对象是个棘手的问题,尤其是你希望在不同的环境中对其进行测试;如果你使用 Jest框架,默认的测试环境是有global对象但没有window对象的nodejs环境。
通过使用globalThis替换window,可以使我们的test模拟window对象变得容易得多:
function showMessage(message) {
globalThis.alert(message);
}
现在当你给这个showMessage函数写单元测试的时候,可以使用globalThis将window进行替换。
it('shows message', () => {
const originalAlert = globalThis.alert;
globalThis.alert = jest.fn();
showMessage('Hello, world!');
expect(globalThis.alert).toHaveBeenCalledWith('Hello, world!');
globalThis.alert = originalAlert;
});
替换后单元测试可以轻易地在不同环境下跑通;
网友评论