I hate to be “that guy” that publishes a blog post and says, “Stop using X” and “Why you should be using X instead”, but after a recent situation in some code I wrote ages ago and updated, I felt it was worthy writing a blog post about why you should use globalThis instead. That’s not to say if you’re currently using window that you’re wrong (because globalThis aliases window in a browser context). However, by using globalThis, you can save yourself a lot of trouble, especially in unit tests.
If you’re not familiar with globalThis, it’s a new global object that was introduced in ECMAScript 2020. It provides a way to access the global object in any environment, whether a web browser, a Node.js server or a web worker. The main benefit of using globalThis instead of window or global is that it makes your code more consistent and future-proof.
Here are a few examples of how globalThis works in different contexts:
In a browser context
In a web browser context, globalThis is essentially an alias for the window object. Here’s an example:
console.log(globalThis === window); // true console.log(globalThis.location.href); // same as window.location.href
By using globalThis instead of window in your code, you can ensure that it will work in any web browser environment.
In a Node.js context
In a Node.js context, globalThis is an alias for the global object. Here’s an example:
console.log(globalThis === global); // true console.log(globalThis.setTimeout === global.setTimeout); // true
By using globalThis instead of global in your code, you can ensure that it will work in any Node.js environment.
In a web worker context
In a web worker context, globalThis is the global object for the worker. Here’s an example:
console.log(globalThis === self); // true console.log(globalThis.postMessage === self.postMessage); // true
By using globalThis instead of self in your code, you can ensure that it will work in any web worker environment.
In unit tests
One of the benefits of using globalThis in your code is that it can make unit testing easier, especially if you need to mock global objects like window or global.
For example, let’s say you have a function that depends on the window object:
function showMessage(message) { window.alert(message); }
To test this function, you might need to mock the window object. However, mocking the window object can be tricky, especially if you want your tests to work in different environments. If you’re using Jest, the default test environment is Node where Window doesn’t exist, but global does.
By using globalThis instead of window, you can make it easier to mock the window object in your tests:
function showMessage(message) { globalThis.alert(message); }
Now, when you’re writing tests for this function, you can mock the globalThis object instead of the window object:
it('shows message', () => { const originalAlert = globalThis.alert; globalThis.alert = jest.fn(); showMessage('Hello, world!'); expect(globalThis.alert).toHaveBeenCalledWith('Hello, world!'); globalThis.alert = originalAlert; });
By using globalThis instead of window, you can write code that’s easier to test and works across different environments.
In conclusion, by using globalThis in your code, you can make it more consistent, future-proof, and easier to test. Whether you’re working in a web browser, a Node.js server, or a web worker
Is self the same as globalThis?
@Abbas Yep. globalThis is just a contextually aware alias for self, window, etc.