The globalThis object translates this sentence into English.
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:
- Environment Agnostic: Points to the top-level
this
value in all JavaScript environments. - Non-Configurable:
globalThis
is a read-only property and cannot be deleted or modified. - 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
- Non-Deletability:
delete globalThis // Returns false in non-strict mode
'use strict'
delete globalThis // Throws TypeError
- 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:
- Initially proposed as
System.global
. - Later changed to
global
, but this conflicted with Node.js'sglobal
. - 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