JavaScript can be executed in different environments, such as browsers, Web workers, Nodes, Deno, etc. The way to access global variables is different in different environments. In a browser, for example, you have window, self, frames, and so on. In the Web Worker, self. In Node, it’s global.

Example:

/* Browser environment */
window === self       // true
window === frames     // true

// Top window
window === parent     // true
window= = =window.top // true

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

Running the same code in a Web Worker or Node environment will generate an error.

/* 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
Copy the code

GlobalThis provides a unified way to access global variables, such as window in the browser environment and Global in the Node environment.

/* Works in most JavaScript runtime environments */
globalThis.msg = 'hello,world'
console.log(msg);
Copy the code

For example, in an SSR project, using window to access global variables is likely to cause errors in server rendering. At this point, changing window to globalThis might solve the problem.

compatibility

With the exception of Internet Explorer, all major JavaScript runtime environments already support globalThis. If you want to be compatible with IE, use the open source Polyfill package github.com/es-shims/gl… .

History project

Before globalThis was widely implemented, a common solution was to use patches like this:

const getGlobalThis = () = > {
	if (typeofglobalThis ! = ='undefined') return globalThis;
	if (typeofself ! = ='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();
Copy the code

To get global variables for the current environment.

But the patch is not perfect, because functions that rely on this in non-strict mode return the characteristics of global objects. In strict mode, the function returns this as undefined.

A more complete, but even stranger, solution:

(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);
Copy the code

See resources for a link to explain why this strange code is better than the previous one and why it is written this way.

conclusion

GlobalThis is currently in Stage 4 of the proposal process, meaning it is ready for release in the next ECMAScript release. So if you don’t need to be compatible with IE, you can use it safely.

The resources

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

Tc39. Es/ecma262 / the mul…

Mathiasbynens. Be/notes/globa…