globalThis 对象

1,097 阅读2分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

前言

ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等

我们一起来学习globalThis 对象吧。

浏览器的全局环境

浏览里的全局对象是谁呢。就是整个窗体,我们有如下几种访问访问到:

  1. window
var win = window;
console.log(win.name);
  1. self
self === window // true
  1. parent 如果不存在被iframe嵌套,用parent也是可以访问到的
parent === window  // true
parent === self  // true
  1. this this是动态的,所以嘛,大家懂的。不靠谱的。
this === window // true
  1. new Function new Function的this全局对象,可以利用这个方案
 new Function('return this')() 

Web Worker 和 Service Worker

这两个的代码块里面,是不能够直接访问到window的,但是可以用self或者 this 访问到全局环境。 当然用this的话,只能在全局作用域,在函数作用域就要小心了。

一段来自MDN的Web Worker的代码

self.onmessage = function (msg) {
    switch (msg.data.aTopic) {
        case 'do_sendWorkerArrBuff':
                sendWorkerArrBuff(msg.data.aBuf)
            break;
        default:
            throw 'no aTopic on incoming message to ChromeWorker';
    }
}

来自MDN的Service Worker的代码段:

this.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
  );
});

Node的全局环境

node环境访问全局环境, 就比较单纯了global

console.log(global)
// Object [global] { ....

node12版本,this是一个没有属性的对象。

console.log(this)
// {}

汇总一下吧

github.com/zloirock/co…

这个版本就比较详细了, 还提到了IE,VM等等,强大。

Browsers~IE8NodeNWWeb WorkersVMFF extensions
selfyesbroken after changing document.domainyesbroken
windowyesyesyesbrokenbroken
globalyesbroken
Function('return this')()breaks CSPyesyesyesbreaks CSPyesyes

globalThis登场

全局环境浏览器和Node里面不统一,就诞生了globalThis。 所以 ES2020 在语言标准的层面,引入globalThis作为顶层对象。

这时候访问一些全局环境变量或者方法就方便了,比如:

globalThis.setTimeout

ES2020才出现的,所以肯定需要垫片:

core-js 这个是相对完善的,不仅仅检查是够存在,还检查Math属性,有意思有意思,真的有意思。

var check = function (it) {
  return it && it.Math == Math && it;
};

// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
module.exports =
  // eslint-disable-next-line es/no-global-this -- safe
  check(typeof globalThis == 'object' && globalThis) ||
  check(typeof window == 'object' && window) ||
  // eslint-disable-next-line no-restricted-globals -- safe
  check(typeof self == 'object' && self) ||
  check(typeof global == 'object' && global) ||
  // eslint-disable-next-line no-new-func -- fallback
  (function () { return this; })() || Function('return this')();

MDN提到的es6-shim

  var getGlobal = function () {
    /* global self, window */
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    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');
  };

MDN提到的global-this

(function (Object) {
  typeof globalThis !== 'object' && (
    this ?
      get() :
      (Object.defineProperty(Object.prototype, '_T_', {
        configurable: true,
        get: get
      }), _T_)
  );
  function get() {
    var global = this || self;
    global.globalThis = global;
    delete Object.prototype._T_;
  }
}(Object));

小结

今天你收获了吗?