Explaining the `globalThis` ES Proposal

Explaining the `globalThis` ES Proposal

The global globalThis property contains the global this value, which is akin to the global object.

The ECMAScript proposal “globalThis” by Jordan Harband provides a new standard way of accessing the global object.

JavaScript’s global scope

JavaScript’s variable scopes are nested and form a tree whose root is the global scope. That scope is only the direct scope when a script runs in a web browser. There are two kinds of global variables:

  • Global declarative variables are normal variables.
  • They are created in the top level of a script, via const, `let, and class declarations.
  • Global object variables are stored in properties of the global object.
  • They are created in the top level of a script, via var and function declarations.
  • They can also be created, deleted, and read via the global object.
  • Other than that, they work like normal variables.

The global object can be accessed via globalThis. The following HTML fragment demonstrates globalThis and the different kinds of global variables.

<script>
 const one = 1;
 var two = 2;
</script>
<script>
 // All scripts share the same top-level scope:
 console.log(one); // 1
 console.log(two); // 2
 
 // Not all declarations create properties of the global object:
 console.log(globalThis.one); // undefined
 console.log(globalThis.two); // 2
</script>

Note that each module has its own scope. Therefore, variables that exist at the top level of a module are not global. The following diagram illustrates how the various scopes are related.

Values of this  

Whenever there is no receiver (the object of a method call), the value of this depends on the current scope:

  • Top level of scripts: global object (in browsers, there is an indirection that we’ll explore later)
  • Top level of ECMAScript modules: undefined
  • During a function call:
  • Strict mode (including modules): undefined
  • Sloppy mode: same as global this

If you call eval() indirectly, it is executed in global scope, sloppily. Therefore, you can use the following code to get the global this:

const theGlobalThis = eval.call(undefined, 'this');

new Function() is also always evaluated in sloppy mode:

const theGlobalThis = new Function('return this')();

There is one important caveat, though: eval, new Function(), etc. are not available if you use CSP (Content Security Policy). That makes this approach unsuitable in many cases.

In browsers, the global this does not point directly to the global object  

As an example, consider an iframe on a web page:

  • Whenever the src of the iframe changes, it gets a new global object.
  • However, the global this always has the same value, which can be checked from outside the iframe, as demonstrated in the feature proposal.

Browsers achieve that by distinguishing two objects:

  • Window is the global object. It changes whenever the location changes.
  • WindowProxy is an object that forwards all accesses to the current Window. This object never changes.

In browsers, global this refers to the WindowProxy; everywhere else, it directly refers to the global object.

globalThis and alternatives (window, etc.) 

globalThis is the new standard way of accessing global this. Existing simple ways depend on the platform:

  • Global variable window: is the classic way of referring to the global object. But it doesn’t work in Node.js and in Web Workers.
  • Global variable self: is available in Web Workers and browsers in general. But it isn’t supported by Node.js. Some people take self appearing in code, as a sign that that code works in both Web Workers and normal browser settings.
  • Global variable global: is only available in Node.js.

The proposal also standardizes that the global object must have Object.prototype in its prototype chain. The following is already true in web browsers today:

> Object.prototype.isPrototypeOf(window)
true

Use cases for globalThis

The global object is now considered a mistake that JavaScript can’t get rid of, due to backward compatibility. It affects performance negatively and is generally confusing.

ECMAScript introduced several features that make it easier to avoid the global object – for example:

  • const, let, and class declarations don’t create global object properties when used in global scope.
  • Each ECMAScript module has its own local scope.

It is normally preferable to refer to global variables as variables and not as properties of globalThis. That has always worked on all JavaScript platforms.

Therefore, there are relatively few use cases for globalThis – for example:

  • Polyfills and shims that provide new features on JavaScript engines.
  • Feature detection, to find out what features a JavaScript engine supports.

A polyfill

The proposal’s author, Jordan Harband, has written a polyfill for globalThis.

Using it with CommonJS syntax:

// Computing the value of `global`
var global = require('globalthis')();

// Shimming global (installing it globally) require('globalthis/shim')();

Using it with ES6 module syntax:

// Computing the value of global
import getGlobal from 'globalthis';
const global = getGlobal();

// Shimming global (installing it globally) import shim from ‘globalthis/shim’; shim();

The package always uses the “most native” approach available (global on Node.js etc., window in normal browser contexts, etc.).

Computing a reference to the global object  

Internally, the polyfill uses the function getPolyfill() to compute a reference to the global object. This is how that is achieved:

polyfill.js:

var implementation = require('./implementation');
module.exports = function getPolyfill() {
 if (typeof global !== 'object' || !global
   || global.Math !== Math || global.Array !== Array) {
   return implementation;
 }
 return global;
};
implementation.js:
if (typeof self !== 'undefined') {
 module.exports = self;
} else if (typeof window !== 'undefined') {
 module.exports = window;
} else if (typeof global !== 'undefined') {
 module.exports = global;
} else {
 module.exports = Function('return this')();
}

FAQ: globalThis  

Why not use global, self, or window everywhere?  

Alas, that is not possible, because many JavaScript libraries use these variables to detect which platform they are running on.

What other names for globalThis were considered?  

An issue in the proposal’s repository lists names that were considered and why they were rejected.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Creating Web Animations with Anime.js

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Do we still need JavaScript frameworks?


javascript es6 web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.