阿里云主机折上折
  • 微信号
Current Site:Index > The globalThis object translates this sentence into English.

The globalThis object translates this sentence into English.

Author:Chuan Chen 阅读数:3411人阅读 分类: JavaScript

The Birth Background of globalThis

The JavaScript runtime environment has become increasingly diverse, ranging from browsers to Node.js, Web Workers, and server-side rendering frameworks. The global objects in different environments vary: window in browsers, global in Node.js, and self in Web Workers. These differences necessitate cumbersome environment checks when writing cross-environment code:

// Traditional environment detection approach
const getGlobal = () => {
  if (typeof window !== 'undefined') return window
  if (typeof global !== 'undefined') return global
  if (typeof self !== 'undefined') return self
  throw new Error('Unable to find global object')
}
const globalObject = getGlobal()

Core Features of globalThis

Introduced in ES2020, globalThis serves as a unified way to access the global object, with the following key characteristics:

  1. Environment Agnostic: Points to the top-level this value in all JavaScript environments.
  2. Non-Configurable: globalThis is a read-only property and cannot be deleted or modified.
  3. Top of the Prototype Chain: Object.getPrototypeOf(globalThis) === Object.prototype.
// Modern approach
console.log(globalThis.setTimeout === window.setTimeout) // true in browsers
console.log(globalThis.require === global.require)     // true in Node.js

Cross-Environment Compatibility Solutions

While modern environments support globalThis, legacy environment compatibility must be addressed:

// Safe polyfill implementation
(function() {
  if (typeof globalThis === 'object') return
  Object.defineProperty(Object.prototype, '__magic__', {
    get: function() {
      return this
    },
    configurable: true
  })
  __magic__.globalThis = __magic__
  delete Object.prototype.__magic__
})()

Practical Application Scenarios

Environment Detection in Modules

// Detect the current runtime environment
const isBrowser = () => 
  typeof globalThis.window !== 'undefined' && 
  globalThis.window === globalThis

const isNode = () => 
  typeof globalThis.process !== 'undefined' && 
  globalThis.process.versions != null &&
  globalThis.process.versions.node != null

Secure Sandbox Implementation

function createSandbox(code) {
  const proxy = new Proxy(globalThis, {
    has(target, key) {
      return true // Trick the 'in' operator
    },
    get(target, key, receiver) {
      if (key === Symbol.unscopables) return undefined
      return target[key]
    }
  })
  
  with(proxy) {
    eval(code)
  }
}

createSandbox(`
  console.log(setTimeout === globalThis.setTimeout) // true
  delete globalThis // Throws an error in strict mode
`)

Comparison with Other Global Access Methods

Access Method Browser Node.js Web Worker Service Worker
window
self
global
globalThis
// Typical differences example
function checkGlobals() {
  return {
    window: typeof window,
    self: typeof self,
    global: typeof global,
    globalThis: typeof globalThis
  }
}

// Browser output: {window: 'object', self: 'object', global: 'undefined', globalThis: 'object'}
// Node.js output: {window: 'undefined', self: 'undefined', global: 'object', globalThis: 'object'}

Handling Special Edge Cases

Behavior in Strict Mode

'use strict'
function test() {
  console.log(this === undefined)       // true
  console.log(globalThis === window)    // true in browsers
}

// Behavior in arrow functions
const arrowFn = () => {
  console.log(this === globalThis)      // true
}

Interaction with the with Statement

const obj = { globalThis: 'custom' }
with(obj) {
  console.log(globalThis) // 'custom' instead of the global object
  // Accessing the real global object requires explicit specification
  console.log(::globalThis) // Using bind syntax
}

Performance Optimization Considerations

Direct use of globalThis offers performance advantages over environment detection:

// Benchmark example
console.time('globalThis')
for (let i = 0; i < 1e6; i++) {
  const g = globalThis
}
console.timeEnd('globalThis') // Typically < 5ms

console.time('environmentCheck')
for (let i = 0; i < 1e6; i++) {
  const g = typeof window !== 'undefined' ? window : 
           typeof global !== 'undefined' ? global : self
}
console.timeEnd('environmentCheck') // Typically > 50ms

Integration with TypeScript

TypeScript has supported the globalThis type since version 3.4:

// lib.es2020.globalThis.d.ts
declare var globalThis: typeof globalThis

// Extending global types
declare global {
  var customGlobalProp: string
}

globalThis.customGlobalProp = 'value' // Correct

Security-Related Considerations

  1. Non-Deletability:
delete globalThis // Returns false in non-strict mode
'use strict'
delete globalThis // Throws TypeError
  1. Shadow Variable Protection:
(function(globalThis) {
  globalThis = 'hacked' // Does not affect the real global object
  console.log(globalThis) // 'hacked'
  console.log(::globalThis === window) // true
})(globalThis)

Historical Evolution and Specification Details

The standardization of globalThis went through multiple proposal stages:

  1. Initially proposed as System.global.
  2. Later changed to global, but this conflicted with Node.js's global.
  3. Finally settled on globalThis to avoid naming conflicts.

Core algorithm defined in the specification:

1. Let envRec be the current execution context's Environment Record.
2. If envRec has a [[GlobalThisValue]] internal slot, return its value.
3. Otherwise, return undefined.

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:import.meta

下一篇:Promise.allSettled()

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.