What is globalThis in Javascript?

Asked

Viewed 166 times

4

I was looking at an example of code and I came across an example that had globalThis:

// timeout de 1s
globalThis.setTimeout(() => alert('Olá'), 1000);

The setTimeout no secrets, but had not yet seen this object globalThis, only the setTimeout alone or something: window.setTimeout.

What is this object globalThis?

  • 1

    Related, but it’s worth a full answer

  • 1

    interesting @Cmtecardeal humm, by name suggests something like a this "global", but it is replacing the window, from what I saw in the question is something like alias, but "multiplatform," that would be?

  • Exactly. He makes a resolve of the global object according to the JS code execution platform.

  • 1

    cool, post an answer with this to document better :)

1 answer

7


Intro

The global object is considered a problem that Javascript cannot get rid of due to backward compatibility. Every developer knows the headache of trying to create/modify/remove some Javascript functionality without breaking any code that makes use of this functionality. In addition, the global object negatively affects the response as demonstrated in this my answer, at least in the browsers.

Ecmascript implemented some features to make it easier to avoid unintentional use of the object global. const and let, for example, they do not create properties on the global object. In addition to in Node.js, each module (script file) has its own scope to avoid affecting the global Node.js. Think of the scope that all the code of the module (file) is within a function.

History

Historically, accessing the global object with Javascript requires a different syntax according to the Javascript code execution environment.

  • In browsers, we can access the global object using window, self or frames

console.log(window);
console.log(self);
console.log(frames);

Even if we make a comparison, we can see that window and frames has the same pointer in memory:

console.log(window === frames); // true

self only works in the context of Web Workers.

  • In Node.js, none of the above works. You should use global:
$ node
Welcome to Node.js v14.15.0.
Type ".help" for more information.
> console.log(global)
// imprime:
// <ref *1> Object [global] {
//   global: [Circular *1],
//   clearInterval: [Function: clearInterval],
//   clearTimeout: [Function: clearTimeout],
//   setInterval: [Function: setInterval],
//   setTimeout: [Function: setTimeout] {
//     [Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
//   },
//   queueMicrotask: [Function: queueMicrotask],
//   clearImmediate: [Function: clearImmediate],
//   setImmediate: [Function: setImmediate] {
//     [Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
//   }
// }
// undefined
// >

It is possible to access the global object through the this in a function without the use of 'use strict', but we know the problems that this can generate.

(function() {
  console.log(this); // => Window {...}
})();

(() => {
  console.log(this); // => Window {...}
})();

(function() {
  'use strict';
  console.log(this); // => undefined
})();

Before the introduction of globalThis, we had two ways to return the global object:

  1. Use of the Function('return this')():

console.log(Function('return this')());

But this form was not the most appropriate, because it generated problems of Content Security Policy.

  1. Use of a custom function. Let’s do an example where we want to know if the setTimeout, for example, it is present in the execution environment. Making a if, we have the code:
var getGlobal = function() {
  if (typeof self !== 'undefined') {
    return self;
  }
  if (typeof window !== 'undefined') {
    return window;
  }
  if (typeof global !== 'undefined') {
    return global;
  }
  throw new Error('unable to locate global object');
};

var globals = getGlobal();

if (typeof globals.setTimeout !== 'function') {
  // setTimeout não está presente nesse ambiente
}

Let’s face it, it’s a lot of code to do something simple.

Currently

With the introduction of globalThis, he is responsible for making a resolve from the context of the Javascript code execution environment and return the global object corresponding to the execution environment. The use of the functions mentioned in 1 and 2 are no longer needed and the code would be much simpler:

if (typeof globalThis.setTimeout !== 'function') {
  // setTimeout não está presente nesse ambiente
}

Usefulness

Where the use of globalThis would be welcome:

  • Resource detection to find out which of them a Javascript execution context supports;

  • Polyfills that provide new features in Javascript engines.

For example, a polyfill can be used to mimic the functionality of an HTML Canvas element in Microsoft Internet Explorer 7, using a Silverlight plugin, or imitate drive support rem CSS or text-shadow; or whatever you want.

  • I never implemented this example, but it worked. Let’s assume you want to create a function digaOla and you want to be able to use it in every environment you run Javascript code. You have the same application adapted to work on your browser, mobile devices, desktop, Iot (why not?) and the soul of the application is in your Node.js server. How to reuse the same function digaOla across the execution context on each platform? Using globalThis and not worrying about writing gigantic codes to support different contexts, checking and testing.

Using in the browser:

if (!globalThis.digaOla) {
  console.log('Posso criar minha função!');

  globalThis.digaOla = function () {
    return 'Olá :)';
  };
} else {
  console.log('Não posso criar minha função!');
}

console.log('Dizendo olá: ', globalThis.digaOla());

How it could be reused and used in Node.js:

Archives:

  |  
   \_ test.js
  |
   \_ test2.js

test2.js:

module.exports = {
  test: () => {
    console.log('De dentro do arquivo test_copy.js: ', globalThis.digaOla());
  }
};

test js.:

if (!globalThis.digaOla) {
  console.log('Posso criar minha função!');

  globalThis.digaOla = function () {
    return 'Olá :)';
  };
} else {
  console.log('Não posso criar minha função!');
}

console.log('Dizendo olá: ', globalThis.digaOla());

const { test } = require('./test2');

test();

Running node test.js:

$ node test.js
Posso criar minha função!
Dizendo olá:  Olá :)
Dizendo olá de dentro do arquivo test_copy.js:  Olá :)

Links:

  • 1

    And the best of globalThis is the polyfill, what a beautiful thing! #sqn

Browser other questions tagged

You are not signed in. Login or sign up in order to post.