
关键词
- ECMA
- JavaScript
- 宿主环境
前言
JavaScript以其独特的语言特性和相对平缓的学习曲线,建立了极其繁荣的生态系统。随着技术的发展,JavaScript 的应用早已超越了最初限定的浏览器环境,渗透到各种各样的环境中。那么,截至 2025 年,JavaScript 究竟可以应用于哪些主要环境呢?
ECMAScript 规范

我们讲 JavaScript 就离不开 ECMAScript (ES) 规范,它是 JavaScript 语言的核心标准。你可以把 ECMAScript 理解为 JavaScript 的设计图,它详细定义了这门语言应该有的语法和功能。
例如,ES 规定了 JavaScript 的语法
- 比如 if/else、for 循环怎么写。
- 数据类型如 string、number、boolean、object、Function 等等。
- 操作符(+、-、===、??)等等。
- 以及一系列**内置对象(例如 Array、Object、Math、Promise、Map、Set 等)**及其对应的方法。
**所有声称支持 JavaScript 的环境和引擎都必须严格遵循 ES 规范,**这样才能确保你写的 JavaScript 代码在不同环境中都能一致地运行
提问:如果我开发了个运行时环境,用的是 JavaScript,但没有 Array 这个类型,作为替代有 List 类型呢?
回答:那就不符合 ES 规范,不能称作 标准 JavaScript
PS: 虽然是那样说,但 ECMA 每年都会发布新的规范,如果你的环境兼容的是 2022 年的 ES,没兼容后面新版本的,也是可以称作符合 ES2022 标准的 JavaScript 环境。
PS: 符合标准与否是根据 ES 版本来的,绝大部分情况下新版本会兼容旧版本。
宿主环境
在开始之前,我们有必要认识一个核心概念:「JS 宿主环境」
-
宿主环境指的是 JS 代码被执行的外部环境。它为 JS 提供了特定的对象和功能,使得 JS 能够与该环境进行交互。
-
你可以理解为,宿主环境是 JS 寄居并利用其能力的地方。不同的宿主环境会提供不同的全局对象和 API。
-
其实也就是运行时环境,JS 在哪里运行,哪里就是宿主环境。
Web

Web 环境,也就是绝大部分**前端开发者最熟悉的环境,**是 JavaScript 的"老家"和最初的舞台。在这里,JS 与 HTML 和 CSS 协同工作,共同构建了我们日常所见的网页。
每个主流浏览器,如 Chrome、Firefox、Edge 和 Safari,都内置了一个引擎。这个引擎负责解析和执行 JS 代码。同时,浏览器还为 开发者 提供了丰富的 Web API,这些 API 使得 JS 能够与浏览器自身、用户界面以及网络进行交互。
值得注意的是,Web API 并不是直接嵌入在 JavaScript 引擎内部的 。当引擎解析 JS 代码,遇到像 document 、fetch 或 setTimeout 这样不属于 ES 规范的功能时,它会将这些操作委託给浏览器这个宿主环境来处理。
核心特点
-
**极为方便的应用切换:**用户无需安装,直接通过 URL 即可访问和切换不同的网页应用。这使得信息的获取和服务的使用门槛极低,极大地提升了用户体验的便捷性。
-
**WebRTC 功能推动新应用普及:**随著 WebRTC 技术的普及和成熟,用户可以直接在浏览器中体验高性能的云端计算服务,比如在线会议、云游戏、云电脑等。
-
**开发者友好与生态繁荣:**Web 开发拥有庞大而活跃的开发者社区,以及丰富的开发工具、框架(如 React、Vue、Angular)和库。这使得 Web 开发对新手十分友好,资源丰富。
-
**跨平台兼容性:**基于标准的 Web 技术,使得开发者可以编写一套代码,就能在不同的操作系统(Windows、macOS、Linux、Android、iOS)和各种设备上运行,实现真正的"一次编写,到处运行"。
-
**自定义插件:**浏览器具备庞大的插件市场,插件的权限通常比网页更高,更有利于开发者做出针对性的体验优化。
不管是在手机还是电脑,浏览器都非常好用,但在如今使用率有较大幅度的下滑,可能是商业原因,也可能是移动互联网的影响。
小程序

近年来,随著移动互联网的发展,**各种小程序(如微信小程序、支付宝小程序、百度小程序、字节跳动小程序等)迅速崛起,**成为 JavaScript 的另一个重要宿主环境。小程序提供了一种无需安装即可使用的应用形态,极大地丰富了移动生态。
小程序环境与浏览器环境是有相似之处的,但也存在很明显的差异。例如:
- 没有标准 Web Api
- 对元素的细粒度修改能力不够
- 组件系统不够丰富
- 较弱的动画能力
- 网络资源限制
核心特点
-
**封闭的运行时:**与开放的 Web 浏览器不同,小程序运行在一个相对封闭和受限的环境中。它没有 DOM 和 BOM,而是提供了一套自定义的组件系统和 API。
-
**特有组件与丰富的设备能力 API:**小程序平台为开发者提供了一套专门用于构建界面的组件系统,例如微信小程序中的 、、 等。这些组件的渲染和行为由小程序宿主环境管理,通常会映射到原生 UI 组件,以提供接近原生的流畅体验。比较值得关注的是,小程序还能直接调用许多移动设备的原生能力,这是传统浏览器 Web JS 难以直接实现的,包括但不限于:
- **支付功能:**直接发起微信支付、支付宝支付等线上支付流程。
- **地理位置服务:**精确获取用户位置、进行导航或周边服务推荐。
- **系统交互:**扫描二维码、分享到社交平台、获取用户信息、发送通知、甚至唤起其他小程序或原生 App。
- **硬件连接:**支持与蓝牙、NFC 等硬件设备进行通信的能力,拓展了更多物联网应用场景。
-
**计算与 UI 双线程架构:**许多小程序平台(尤其是微信小程序)採用了逻辑层与视图层分离的双线程架构。
- **计算层:**JavaScript 代码运行在独立的 JS 引擎线程中,负责处理数据、业务逻辑和网络请求。它与视图层的通信是异步的。
- **视图层:**负责界面的渲染,通常基于原生组件或经过优化的 WebView 进行高效渲染。
对于有一定经验的前端开发者来说,从 web 转小程序基本是没难度的,而且得益于微信、支付宝等软件的巨大生态,就算小程序某些情况下性能体验不尽人意,也会有海量用户使用。
服务端(Node.js)

JavaScript 不仅在前端和移动端大放异彩,在服务器端开发也佔据了举足轻重的地位。这裡的明星就是 **Node.js,它让 JavaScript 能够在浏览器之外的任意位置运行,**开启了全栈 JavaScript 开发的时代。
**前端与 Node.js 是相辅相成的,**可以说没有 Node.js 就没有现在的前端,因为 Node.js 不仅提供了服务器端的能力,更是许多前端工具链(例如打包构建工具、模块管理器、开发服务器等)的基石。
核心特点
-
**基于 V8 引擎的高性能:**Node.js 内置了与 Chrome 浏览器同款的 V8 JavaScript 引擎。V8 引擎能将 JavaScript 代码高效地编译为机器码执行,这让 Node.js 在服务器端也能提供出色的性能表现,当对性能有极致要求时,还可以通过加载 C++ 或 Rust 编写的模块来突破瓶颈,灵活性直接拉满。
-
**庞大的 NPM 生态系统:**Node.js 拥有全球最大的开源包管理工具 NPM (Node Package Manager)。NPM 仓库中包含了数百万个可重用的开源模块,覆盖了从 Web 框架(如 Express.js、Koa.js)到数据库驱动、测试工具等各个方面。这个庞大的生态极大提高了开发效率,让开发者能快速构建复杂的应用。
-
**非阻塞 I/O 与事件驱动:**这是 Node.js 最核心的设计理念。它不是为每个请求都创建一个新线程,而是通过单线程的事件循环 (Event Loop) 来处理所有操作。当遇到 I/O 操作(如读写文件、网络请求)时,Node.js 会将任务交给底层系统处理,然后立即返回并处理其他请求,待 I/O 操作完成后再通过回调机制通知 Node.js。这种模式让 Node.js 在处理大量并发连接时非常高效,特别适合 I/O 密集型应用(其实依旧是多线程,只不过其他线程处理的事情跟 JS 代码没关系)。
-
**全栈 JavaScript 开发:**Node.js 最大的吸引力之一是,它让开发者可以使用同一种语言------JavaScript------来处理前端和后端逻辑。这简化了技术栈,降低了团队协作和开发者切换环境的门槛。
服务端编程语言拥有的权限非常高,既可以对接前端搓出 HTTP 服务器、处理客户端请求,更能在底层与操作系统交互,甚至能打包成 exe 等可执行文件做 PC 应用。理论上,Node.js 可以控制电脑的一切系统资源和行为
PC 应用 (桌面应用)

JavaScript 不仅能在浏览器中运行,**也能开发原生的桌面应用程序。**这类应用通常具备跨平台能力,能在 Windows、macOS 和 Linux 等主流操作系统上运行。对于熟悉 Web 技术栈的开发者来说,这提供了将前端技能延伸至桌面应用领域的便捷途径。
目前,主流的 JavaScript 桌面应用开发框架主要有 Electron 和近年来兴起的 Tauri。它们各自採用不同的策略来实现跨平台桌面应用的能力。
Electron (GitHub)
在 Electron 应用中,UI 界面本质上是一个运行在内置 Chromium 浏览器中的 Web 页面,JavaScript 负责界面的交互逻辑。而 Node.js 环境则提供了访问操作系统底层能力(如文件系统、进程管理、网络通信等)的 API。这使得桌面应用能够执行传统 Web 应用无法完成的系统级任务。
在开发 Electron 应用时,你需要同时操作两个环境。
Tauri (Commons Conservancy)
Tauri 是一个相对较新的框架,它基于 Rust 语言构建后端逻辑,并使用操作系统原生的 WebView(如 Windows 上的 WebView2, macOS 上的 WKWebView)来渲染前端界面。
在 Tauri 应用中,前端部分依旧是用 JavaScript 来写,但服务端部分根据需求可能需要写 Rust
核心特点
-
**跨平台开发:**无论是 Electron 还是 Tauri,都允许开发者使用一套 JavaScript (以及相关 Web 技术) 代码库来构建适用于 Windows、macOS 和 Linux 的独立应用程序,比较新颖的 Tauri 甚至已经有实验性功能可以开发 App。
-
**Web 技术栈复用:**前端开发者可以将其熟悉的 HTML、CSS 和 JavaScript 技能直接应用于桌面应用开发,降低了学习曲线和开发成本。
-
**原生系统集成:**通过 Node.js (Electron) 或 Rust 后端 (Tauri) 的原生系统能力,桌面应用可以访问本地文件系统、操作系统级通知、系统菜单、剪贴板、原生对话框、以及其他系统 API,实现与操作系统的深度集成,拥有当前电脑登录用户的最高控制权限。
-
**丰富的 UI 库支持:**可以使用所有 Web 前端框架和库(如 React、Vue、Angular)来构建界面,提供灵活多样的 UI 设计,如果使用的是 Electron,还可以拥有上面 Node.js 环境的所有特点。
Electron 的前身于 2013 年问世,在 2015 年正式改名,**发展到今年,已经有 12 年的历史,目前 GitHub 上还在更新,**这么多年来,建立了无数令人激动的应用,开源的特性也让无数开发者使用它编写了第一款 PC 桌面应用,生态极其繁荣,虽然性能方面由于 JS 的限制与早期架构方面的问题,稍弱于现代框架。
**但正如我们在 Node.js 部分提到的那样,JavaScript 的特点就是灵活,**如果实在对性能要求高,还可以加载 C++插件和 Rust 插件。
移动 App

在移动 App 开发领域,JavaScript 同样扮演著重要角色,而 React Native 便是其最具代表性的框架。它允许开发者运用 Web 技术的思维和生态,来构建功能完整的原生应用程式。
名字以 React 开头,那它跟 React 有什么关系呢?
- 同一个组织开发的,设计概念高度统一
- 完全采用了 React 的组件化思想、语法以及数据流管理方式。这意味著 Web 开发的经验可以无缝迁移
与原生 App 的区别是什么?
- RN 当需要操作原生功能或 UI 时,它须通过一个桥接层机制与原生层进行非同步通信。而原生 App 则直接在主线程上与系统 API 交互。
- 由于桥接层的存在,在需要大量、频繁原生交互的极端场景下,RN 的性能会逊于纯原生应用。然而,在绝大多数业务场景中,其性能表现足以提供流畅的用户体验。
核心特点
-
极高的开发效率: 由于类 React 的特性,开发者能以较低的成本快速开发移动 App,非常适合个人开发者快速开发应用验证市场。
-
成熟且稳定的热重载机制: 设计初就有良好的热重载的特性,能让其像 Web 开发一样修改实时响应。
-
成熟的生态系统: 背靠庞大的 JavaScript 和 React 社群,开发者可以轻易地找到数以万计的现成函式库和工具,从状态管理到複杂的图表,几乎能涵盖所有需求。
-
跨平台特性: 通常使用 RN 可以用一套代码部署到安卓和 ios 两大热门平台
在环境上,RN 拥有跟原生 App 相同的操作权限,但在实际操作时,你会发现当涉及到 Native 模块 的时候,你得额外编写或引入由(Kotlin/Java 或 Swift/Objective-C)等语言编写的原生模块,然后再通过桥接层机制暴露给 JavaScript 使用。
也就是说,你如果只会前端知识,那开发机制复杂的 App 可能够呛,并且**RN 的架构是多层抽象的,可能是你某一个 JS 函数报错了,但却会在原生模组的内部(如 Java 或 Swift 层)爆发。**这会导致错误堆叠不直观,信息隐晦。开发者不仅需要熟悉 JS 的调试工具,还常常被迫打开 Android Studio 或 Xcode,去面对他们可能完全不熟悉的原生开发环境和日志系统,
游戏开发

游戏的本质,可以看作是动画与交互的结合体。从运行平台来看,使用 JavaScript 开发的游戏,主要可以分为三大类:网页游戏、桌面客户端游戏、以及手机游戏。
以 Cocos 引擎为例,它作为一个以 JavaScript/TypeScript 为核心的游戏引擎,可以将同一套代码发布到这所有三种平台。这也意味著,Cocos 引擎巧妙地为我们的 JS 适配了三种完全不同的环境。
-
网页游戏: Cocos 会将你的游戏专案打包成能在浏览器中运行的标准 Web 文件。在这种模式下,浏览器就是宿主环境,其提供的 WebGL/Canvas 等 API 负责实际的渲染,这与常规的网页应用在环境上没有本质区别。
-
桌面客户端游戏: 这与 Electron 架构不同。用 Cocos 发布游戏到桌面端后,将是一款真正的 C++ 应用,其核心是"C++ 原生应用框架 + C++ 渲染引擎 + 内嵌的 JavaScript 引擎"。这样做主要是为了追求极致性能,其宿主环境暴露给 JS 的是一套完整的游戏引擎 API(如场景、节点、精灵等),而非 Electron 所提供的 DOM 和 Node.js API。但在环境权限上,它依旧跟其它原生桌面应用一样。
-
手机游戏: 其底层架构与 React Native 表面相同,都是"原生 App + 内嵌 JS 引擎"的模式。但本质区别在于,JS 在 Cocos 中只作为**"大脑"负责游戏逻辑,向高效的 C++ 渲染引擎下达绘图指令;而在 React Native 中,JS 除了逻辑,还负责介面的布局与构成。因此,它们的宿主环境也完全不同:Cocos 向 JS 暴露的是一套游戏引擎 API**,而 React Native 暴露的则是一套用于创建和控制原生 UI 组件的 API,两者在环境权限上虽同为原生级,但能力和专长领域截然不同。
游戏开发非常复杂,如果只有单纯的前端知识大概率是开发不了的,使用 Cocos 引擎开发游戏时,纯粹的编写(JavaScript)只是工作流的一部分。一个游戏的成败,同样高度依赖于游戏策划、美术建模、场景搭建和动画设计等非程式设计环节等等。
MCP 应用

首先,我们需要定义这个概念。这里的"MCP 应用",我们将其广义地理解为以大型语言模型(LLM)为核心,能够理解并代理执行开发任务的工具包。
与传统开发略有不同,在之前讨论宿主环境时,都是想着宿主环境能提供给 Js 什么,而在 MCP 应用开发中,我们的角色就转变了,变成了我们要给 LLM 模型提供什么。
换句话说,我们才是宿主。
在这个新模式下,我们主要的开发工作,就是用 JS 定义一堆"工具"给 LLM 使用。这些工具可以是档案读写、执行终端命令、调用 API 等任何原子操作。我们不再编写"如果...就..."的死板流程,而是为 LLM 提供解决问题的能力选项。
我们是身体,LLM 是大脑。
核心特点
-
C/S 架构的工具包: MCP 应用 依旧用了我们都熟悉的 C/S 架构,所以如果做过服务端开发,大部分情况下开发范式也能继续沿用。
-
单一的环境: 通常情况下,我们只会使用 Node.js 等具备服务端环境的来编写代码给 LLM 使用。
-
高度工具化与原子化的函式设计: 我们编写的 JS 函数更像是一个个独立的"Unix 命令"。每个函式(工具)都应该只做一件事,并且做得很好(原子性)。它们通常是无状态的,因为维护任务状态和上下文的责任,已经被转移给了"大脑"。
-
非确定性的输出与"涌现"能力: 传统程式码的输入和输出是高度确定的。但在 MCP 应用中,面对同一个目标,LLM 这次可能会选择 工具 A -> 工具 B 的路径,下一次可能会选择 工具 C -> 工具 A 的路径。这种非确定性正是其智能的体现。更重要的是,透过简单工具的组合,LLM 可能会解决你从未预料到的複杂问题,这就是系统的**"涌现 (Emergence)"能力**。
目前 MCP 处在高速发展的阶段,市场上也有很多有趣的 MCP 服务可以使用,有兴趣的读者可以访问awesome-mcp-servers了解下。
区块链(Web3)

JavaScript 在 web3 领域,通常就做两种类型的开发,一种是 Dapp 应用,一种是智能合约。
Dapp 应用大部分是基于标准 web 环境的,然后上层应用会额外提供一些 web3 的接口来给 JavaScript 操作,也就是说,跟传统 web 环境没有太大区别。
在部分现代公链上,JS 已经可以直接用来编写在区块链上运行的"智能合约",例如在 NEAR Protocol 或 Internet Computer (ICP) 这样的区块链上,你的 JS 代码会被部署到区块链的节点上,在一个高度隔离、确定性的沙箱虚拟机中运行。这个沙箱环境极其严苛,它不提供任何非确定性的 API(如 Math.random() 或 Date.now()),因为所有节点运行同一份合约程式码后必须得到完全一致的结果。JS 在这裡扮演的是"规则制定者",其程式码定义了 DApp 的核心业务逻辑,并被永久、不可篡改地记录在区块链上。
核心特点
-
用户即所有者,与钱包的交互模式: ,这是 Web3 开发与传统 Web 开发最根本的区别。在 Web3 中,用户的身份、资产(代币、NFT)和权限,都由用户自己的钱包(如 MetaMask)掌管,而非储存在我们的伺服器上。因此,我们的 DApp 前端 JS 应用,其工作模式不再是"请求用户注册登录",而是:
- **请求连接:**向用户的钱包请求授权,以读取其公开的钱包地址。
- 请求签名:当需要执行写入操作(如交易)时,向用户的钱包发起请求,由用户亲自确认并签署,我们的应用自始至终无法接触到用户的私钥。
-
不可变的后端,与智能合约的交互: 在 DApp 的世界里,智能合约就是后端。这个后端一旦部署,其代码和规则就是不可篡改的。我们的 JS 前端与这个"特殊后端"的交互也分为两种:
- 读取 (Read): 调用智能合约的"视图方法",直接从区块链节点读取数据。这个过程通常是免费、快速的,类似于发起一个 GET 请求。
- **写入 (Write):**调用智能合约的"调用方法"来改变链上状态。这是一个非同步交易,需要用户签名、支付 Gas 费,并且需要等待区块链确认,速度相对较慢。
编写 DApp 时,大部分情况下都与我们编写 web 网页差不多,但是在**编写智能合约时,跟以往的设计思维都不一样,这里环境受限于区块链本身的特性,你无法像常规服务端应用那样,什么都能改,就算换语言也一样。
嵌入式 (Embedded Systems)

嵌入式系统通常会被设计为功能专一、高度整合的电路板,在物理层面,大部分民用的只会是比较简陋或 mini 的一种板子,这种情况带来的就是资源极其有限以及对效率的高要求,在嵌入式开发时,讨论的内存单位不是 GB,也不是 MB,而是只有可怜的 KB 级别,这种情况下,就不可能把传统的 JS 引擎打包进去了。
可能看到这你有疑问了,在这种情况下,JS 还能飞?
答案是可以,因为它用可接受的性能损耗,换来了传统 C/C++ 开发模式难以企及的优势。
- 极高的开发测试效率: Espruino、Moddable SDK 等嵌入式 JS 环境,通常提供 REPL (互动式命令列)。开发者可以通过直接连线到硬件,逐行"发号施令",硬件就得逐行响应。这种"所见即所得"的硬件操控,对于原型验证和快速迭代的效率提升是非常高的。
- 与生俱来的事件驱动模型: Web 开发者可以几乎零成本地将 element.addEventListener 的事件驱动思维,平移到 setWatch() 这样的硬件监听上,用最熟悉的方式驾驭硬件。
- 降低硬体开发门槛: 最主要的一点,由于 JS 开发者尤其多,此举让数以百万计的开发者,也能相对轻松地参与到创造物理实体世界的游戏中来。
核心特点
-
极其有限的资源: 这是所有设计决策的出发点。你的 JS 代码运行在一个连基本操作系统都没有的"裸机"环境。每一个变量声明、每一次函数调用,都在消耗着以 KB 计算的宝贵内存。开发者必须像在真空的宇宙中一样,珍惜每一次呼吸、每一个动作,时刻关注代码的内存占用和资源消耗。
-
极其受限的接口: 在这个环境中,没有 window,没有 document,甚至没有 Node.js 中理所当然的 fs、http 等高级模块。宿主环境暴露给 JS 的,是一套极简的、直接与硬件交互的底层 API,例如 digitalWrite()(控制引脚高低电平)、analogRead()(读取模拟信号)、I2C.setup()(设置 I²C 通信)。所有功能都需要从最底层的物理操作开始构建。
-
物理意义上的所见所得: 这是嵌入式开发最独特的魅力所在。你的代码不再仅仅是改变屏幕上的像素颜色,而是直接在物理世界产生效果。led.on() 会让一颗真实的 LED 灯亮起;motor.move() 会让一个真实的马达转动;getTemperature() 读取的是你周围环境的真实温度。代码与现实世界的交互是即时的、可触摸的,这种直接的反馈循环,能带来与纯软件开发完全不同的成就感。
那么,JavaScript 会取代 C/C++ 成为嵌入式开发的主流吗? 答案显然是否定的。在汽车、航太、医疗等对"即时"和极致可靠性有着零容忍要求的领域,C/C++ 的地位无可撼动。
然而,在智慧家居、互动艺术、消费性电子产品以及广阔的物联网世界中,敏捷的开发效率和无缝的云端整合能力,其重要性往往超越了对极致运行性能的追求。在这些领域,像 Moddable SDK 等基于 JS 的方案,已经在许多商业产品中得到了成功验证。
总结
**JavaScript 的前身非常草根,**但它就像小说主角一样,意外"捡到"了名为"浏览器"的"老爷爷",从此一路过关斩将。经过近 30 年的迭代,如今依然保持著极高的活力与恐怖的适应力。
当然,这离不开每一位开发者的支持和建设。正是这个全球最大、最活跃的开发者社群,用一行行代码、一个个开源包(你好,NPM!),共同将它从一门小小的脚本语言,抬成了如今横跨前后端、云端、甚至物理世界的**"六边形战士"。**