1 global 全局对象
在 ECMAScript 规范中定义了 The Global Object,在不同的 JavaScript 环境中有着不同的实现。
在浏览器中,可以通过 window
获取全局对象,它同时表示当前页面的窗口。对于多标签页的浏览器而言,每个标签页都有一个独立的执行环境,有着自己的 window
对象。页面中如果包含 <iframe>
元素,每个 iframe 也都存在一个独立的执行环境,对应 iframe.contentWindow
对象。如果使用了 Web Worker,每个 Worker 线程也都有各自独立的执行环境,略微不同的是在 Worker 线程内仅可以通过 self
获取全局对象。
在 Node.js 中可以通过 global
获取全局对象。
在松散模式(sloppy mode)下,可以通过 this
在函数中获取全局对象。在严格模式(strict mode)下,函数中的 this
返回 undefined
。在 ES Modules 中,this
返回 undefined
。
目前的 globalThis 提案 提供一个标准的方式来获取 ECMAScript 规范定义的 global 全局对象。
2 全局对象上的属性
通常讨论全局对象时,很少会区分全局对象是 global 对象,还是 global 对象上的属性。由于作用域链的原因,global 对象上的属性都可以直接在全局访问。不同的 JavaScript 环境存在不同的全局对象,例如浏览器中的 window
、self
、location
、navigator
、event
,Node.js 中的 global
、module
、exports
、process
等。访问宿主环境中不存在的全局变量会产生 ReferenceError
错误(即访问未声明变量)。
2.1 浏览器的全局对象
浏览器中包含 JavaScript、BOM、DOM、CSSOM 等 API,它们大都通过 window
或者 document
对象暴露给开发者。
2.1.1 window
对象上的属性
以下属性摘录自 The Window object - HTML Standard 及相关规范。
- The Window object
window.window
,window.frames
,window.self
: These attributes all return window.window.document
: Returns theDocument
associated with window.document.defaultView
: Returns theWindow
object of the active document.
- APIs for creating and navigating browsing contexts by name
window = window.open([url[,target[,features]]])
: Opens a window to show url (defaults to about:blank), and returns it. The target argument gives the name of the new window. If a window exists with that name already, it is reused. The features argument can be used to influence the rendering of the new window.window.name[=value]
: Returns the name of the window. Can be set, to change the name.window.close()
: Closes the window.window.closed
: Returns true if the window has been closed, false otherwise.window.stop()
: Cancels the document load.
- Accessing other browsing contexts
window.length
: Returns the number of document-tree child browsing contexts.window[index]
: Returns the indicated document-tree child browsing context.
- Named access on the Window object
window[name]
: Returns the indicated element or collection of elements. As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, usedocument.getElementById()
ordocument.querySelector()
.
- Navigating related browsing contexts in the DOM
window.top
: Returns theWindowProxy
for the top-level browsing context.window.opener[=value]
: Returns theWindowProxy
for the opener browsing context. Returns null if there isn't one or if it has been set to null. Can be set to null.window.parent
: Returns theWindowProxy
for the parent browsing context.window.frameElement
: Returns theElement
for the browsing context container. Returns null if there isn't one, and in cross-origin situations.
- The Location interface
window.location[=value]
/document.location[=value]
: Returns.Location object with the current page's location. Can be set, to navigate to another page.
- The Navigator object
window.navigator
/self.navigator
- The History interface
window.history
- Browser interface elements
window.locationbar
window.menubar
window.personalbar
window.scrollbars
window.statusbar
window.toolbar
window.status
window.event
- Images
promise = self.createImageBitmap(image [, options ])
promise = self.createImageBitmap(image, sx, sy, sw, sh [, options ])
- Animation frames
self.requestAnimationFrame(callback)
self.cancelAnimationFrame(handle)
- Cooperative Scheduling of Background Tasks
window.requestIdleCallback(callback, options)
window.cancelIdleCallback(handle)
- Timers
handle=self.setTimeout(handler[, timeout[, arguments...]])
handle=self.setTimeout(code[, timeout])
self.clearTimeout(handle)
handle=self.setInterval(handler[, timeout[, arguments...]])
handle=self.setInterval(code[, timeout])
self.clearInterval(handle)
- Microtask queuing
self.queueMicrotask(callback)
- Simple dialogs
window.alert(message)
window.confirm(message)
window.prompt(message[, default])
- Printing
window.print()
- XMLHttpRequest API
XMLHttpRequest
FormData
ProgressEvent
- Fetch API
Body
Headers
Request
Response
self.fetch(input, init)
- High Resolution Time
window.performance
- Base64 utility methods
result = self.btoa(data)
result = self.atob(data)
- CSSOM View Module
window.matchMedia()
window.screen
- browsing context
window.moveTo(x, y)
/window.moveBy(x, y)
window.resizeTo(x, y)
/window.resizeBy(x, y)
- viewport
window.innerWidth
window.innerHeight
- viewport scrolling
window.scrollX
/window.scrollY
window.pageXOffset
/window.pageYOffset
window.scroll(options)
/window.scroll(x, y)
window.scrollTo(options)
/window.scrollTo(x, y)
window.scrollBy(options)
/window.scrollBy(x, y)
- client
window.screenX
/window.screenY
window.screenLeft
/window.screenTop
window.outerWidth
/window.outerHeight
window.devicePixelRatio
- etc.
在浏览器中定义全局变量时,需要注意变量命名,避免与 window
对象上的属性重名。
如:
var status = [1, 2, 3];
console.log(status); // '1,2,3'
typeof name; // 'string'
2.1.1.1 window.frames
和 iframe 的关系
<iframe src="1.html" id="iframe-1"></iframe>
<iframe src="2.html" id="iframe-2"></iframe>
window.length; // 2
window.frames === window; // true
window.frames[0] === document.getElementById('iframe-1').contentWindow; // true
window.frames[1] === document.getElementById('iframe-2').contentWindow; // true
2.1.2 Worker 中可用的全局对象
Worker 中无法获取 document
和 window
对象。以下属性摘录自 The WorkerGlobalScope object - HTML Standard:
workerGlobal.self
: Returns workerGlobal.workerGlobal.location
: Returns workerGlobal's WorkerLocation object.workerGlobal.navigator
: Returns workerGlobal's WorkerNavigator object.workerGlobal.importScripts(urls...)
: Fetches each URL in urls, executes them one-by-one in the order they are passed, and then returns (or throws if something went amiss).
2.2 Node.js 的全局对象
以下属性摘录自 Global Objects - Node.js:
Buffer
__dirname
__filename
clearImmediate(immediateObject)
clearInterval(intervalObject)
clearTimeout(timeoutObject)
console
exports
global
module
process
queueMicrotask(callback)
require()
setImmediate(callback[, ...args])
setInterval(callback, delay[, ...args])
setTimeout(callback, delay[, ...args])
TextDecoder
TextEncoder
URL
URLSearchParams
WebAssembly
2.3 获取所有的全局对象
可以通过遍历 window
或者 global
对象获取执行环境中所有的全局对象。
// 包括浏览器内置 DOM 对象
Object.keys(window);
// 包括浏览器内置对象、Command Line API 和 Chrome Extension 等注入的全局变量
Object.getOwnPropertyNames(window);
2.4 获取所有非内置的全局对象
可以通过创建一个新的 iframe,比对两者的 window
对象,获取所有非内置的全局对象。
(function () {
function getNonBuiltinProps() {
var nonBuiltinObjects = {};
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
var builtinPropKeys = Object.keys(iframe.contentWindow);
Object.keys(window).forEach(function (key) {
if (!builtinPropKeys.includes(key)) {
nonBuiltinObjects[key] = window[key];
}
});
document.body.removeChild(iframe);
return nonBuiltinObjects;
}
console.log(getNonBuiltinProps());
})();
2.5 在 UMD 模块中的使用
在 UMD Wrapper 中便是通过判断 CommonJS、AMD 特有的对象来暴露模块。
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? module.exports = factory(require('lodash'))
: typeof define === 'function' && define.amd ? define(['lodash'], factory)
: (global.MyModule = factory(global._));
}(this, (function (lodash) { 'use strict';
//
})));
webpack 在打包 JS,处理 global 对象时,支持多种配置,默认为 window
,无法在 Node.js 中使用。
output.globalObject
- webpack- Can't create UMD build which can be required by Node #6522 - webpack
- Add
target: "universal"
#6525 - webpack - UMD build can't be used in node env #6784 - webpack