JavaScript 三种平台及判断方法

根据MDN描述:

在以前,从不同的 JavaScript 环境中获取全局对象需要不同的语句。

在 Web 中,可以通过 window、self 或者 frames 取到全局对象,但是在 Web Workers 中,只有 self 可以。在 Node.js 中,它们都无法获取,必须使用 global。

在松散模式下,可以在函数中返回 this 来获取全局对象,但是在严格模式和模块环境下,this 会返回 undefined。

您也可以使用以下代码获取全局对象this:

Function('return this')()

但是禁用eval()的环境(例如浏览器中的CSP)会阻止以这种方式使用Function。

globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身)。

不像 window 或者 self 这些属性,它确保可以在有无窗口的各种环境下正常工作。所以,你可以安心的使用 globalThis,不必担心它的运行环境。

为便于记忆,你只需要记住,全局作用域中的 this 就是 globalThis。

三种平台及判断方法

  • Web 普通浏览器平台 包括electron平台的渲染线程
  • WebWorker 前端实现"后台计算"的主要途径
  • Node.js worker_threads模块 包括electron平台的主线程

如何判断? 使用通用的全局对象globalThis, 这里提出两种判断方法.

第一种方法, 判断globalThis.constructor.name的值, 上面三平台依次表现为:

  • Window
  • DedicatedWorkerGlobalScope
  • Object

第二种, 判断不同平台特有的globalThis的字段:

  • 含有globalThis.process的是Node.js
  • 否则, 含有globalThis.window或者globalThis.document的是Web
  • 否则, 含有globalThis.FileReaderSync的是WebWorker

代码如下:

/**
 * 判断运行平台
 * 第一种方法, 判断globalThis.constructor.name的值:
 * Window、DedicatedWorkerGlobalScope、Object
 * 第二种, 判断不同平台特有的globalThis的字段:
 * 含有`globalThis.process`的是Node.js
 * 否则, 含有`globalThis.window`或者`globalThis.document`的是Web
 * 否则, 含有`globalThis.FileReaderSync`的是WebWorker
 */
function js_platform() {
    if (globalThis.constructor.name === 'Window') return 'web';
    if (globalThis.constructor.name === 'DedicatedWorkerGlobalScope') return 'worker';
    if (globalThis.constructor.name === 'Object') return 'node';
    return globalThis.process ? 'node' : (globalThis.window ? 'web' : (globalThis.FileReaderSync ? 'worker' : 'unknown'));
}