如果你打开浏览器的开发者工具,在控制台输入 console.log(window),会看到一个巨大的对象,里面包含了你所能调用的几乎所有 API。这些 API 并非全部来自 JavaScript 语言本身,而是由三个部分共同构成:ECMAScript、DOM 和 BOM。理解这三者的边界与关系,是厘清 JavaScript 能力范围的关键。
1.4.1 ECMAScript:语言的骨架
ECMAScript(简称 ES)是 JavaScript 的语法和语义标准,由国际标准化组织 ECMA 制定。它规定了语言的核心能力,包括:
- 数据类型(
Number、String、Boolean、Object等) - 语法结构(
if、for、function、class等) - 内置对象(
Array、Date、RegExp、Promise等) - 执行模型(作用域、原型链、事件循环等底层机制)
可以把 ECMAScript 想象成一套“语言规范说明书”,它与具体的运行环境无关。无论是浏览器里的 V8 引擎,还是 Node.js 里的 V8 引擎,它们都根据同一份 ES 规范实现了语言的核心部分。因此,你在任何环境下写 Array.prototype.map、Promise.all、const 声明,行为是一致的。
关键特征:
- 标准化驱动:从 ES6(2015)开始,每年发布一个新版本,持续为语言增加新能力(如箭头函数、模板字符串、可选链等)。
- 不包含与平台相关的 API:ECMAScript 不提供操作网页、读写文件、发送网络请求的能力,这些都由宿主环境提供。
1.4.2 DOM:操作网页内容和结构的接口
DOM(Document Object Model,文档对象模型)是浏览器将 HTML 或 XML 文档解析后生成的一个树状对象模型。它提供了一套 API,让 JavaScript 可以动态地增、删、改、查网页上的元素、属性和样式。
// 选择页面上的某个元素并修改其内容
const title = document.querySelector('h1');
title.textContent = '你好,DOM!';
// 创建新元素并插入到页面中
const newParagraph = document.createElement('p');
newParagraph.innerText = '这是通过 JavaScript 动态添加的段落。';
document.body.appendChild(newParagraph);
通过 DOM,你可以:
- 根据 id、class、标签名等查找节点
- 改变元素的文本、HTML、样式
- 监听用户交互事件(点击、输入、滚动等)
- 动态创建、删除或移动节点
DOM 不是 JavaScript 语言的一部分,而是浏览器提供的一套 Web API。其他编程语言(如 Python)也能在特定环境中操作 DOM,但 JavaScript 是浏览器的原生“搭配”,拥有最自然、最强大的操控能力。W3C 为 DOM 制定了标准,主流浏览器都遵循这些规范,但细微的兼容性差异仍可能存在。
实用要点:
- 所有 DOM 操作都离不开
document对象,它是 DOM 树的入口。 - 频繁的 DOM 操作成本较高,容易触发浏览器重排和重绘,影响性能。因此在实际项目中,我们会借助虚拟 DOM、批量更新等策略来优化。
1.4.3 BOM:与浏览器窗口交互的接口
BOM(Browser Object Model,浏览器对象模型)提供了一系列与浏览器自身功能交互的对象和方法,它没有统一的标准,但各大浏览器实现了一套高度相似的接口。核心对象包括:
window:浏览器窗口对象,既是全局对象,也是 BOM 的顶层入口。所有的全局变量、全局函数都会挂载在window下。location:获取/设置当前页面的 URL,实现页面跳转或刷新。navigator:提供浏览器和操作系统的信息,常用于能力检测(如是否支持某个 API)。history:浏览历史的管理,让单页应用能实现前端路由(前进、后退)。screen:屏幕尺寸、色深等信息。- 定时器:
setTimeout、setInterval、requestAnimationFrame等,用于控制代码的执行时机。
一个典型的 BOM 操作示例:
// 获取当前 URL,并进行页面跳转
console.log(location.href); // 输出完整 URL
if (confirm('是否跳转到新页面?')) {
location.href = 'https://example.com';
}
// 检测浏览器是否支持 Geolocation API
if ('geolocation' in navigator) {
console.log('支持地理位置');
}
BOM 的重要性:
虽然 BOM 没有像 DOM 那样严格的公共标准,但它连接着 JavaScript 代码和浏览器的外壳功能,让开发者能够控制窗口行为、管理历史记录、获取设备信息。在单页应用(SPA)中,history.pushState() 配合前端路由框架,实现了无刷新的页面导航体验。
1.4.4 三者的协同关系
用一张简单的图来理解它们的分工:
┌────────────────────────────────────────────┐
│ 浏览器 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ BOM │ │ DOM │ │ 其他 API │ │
│ │ (window, │ │(document)│ │(WebGL, │ │
│ │location…)│ │ │ │ WebRTC…) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └──────────────┼──────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ECMAScript │ │
│ │ (语言) │ │
│ └───────────┘ │
└────────────────────────────────────────────┘
- ECMAScript 定义了基础语言能力,它是一切的根基。没有它,变量、函数、循环都无从谈起。
- DOM 和 BOM 是浏览器为 JavaScript 赋予的“超能力”,让语言能够真正操纵网页和浏览器。
- 三者结合 = 你所能调用的全部 Web API。你写下的每一行 JavaScript 代码,都是在 ECMAScript 的语法规则下,调用 DOM、BOM 以及其他 Web API 以实现功能。
理解这三个组成部分的意义在于:你不会再混淆“这是 JavaScript 的语法”和“这是浏览器的 API”。当你需要在 Node.js 中运行时,DOM 和 BOM 都不存在,但 ECMAScript 核心依旧可用(再加上 Node.js 自己的 API)。这种清晰的分离,也让你在学习任何新环境时,能快速定位哪些能力是通用的,哪些是环境专属的。