全网最全 ECMAScript 攻略( 更新至 ES2026)

3 阅读56分钟

本文写于 2021 年,每年随新标准发布迭代一版。得益于 Claude 的助力,今年这一版做了历年最大的一次更新:ES2026 新特性逐个详解、全文改为时间降序、TC39 提案与 Ecma 会员动态都做了深挖。

先花一分钟,速览过去一年 JavaScript 标准世界都发生了什么:

  • ES2026 正式通过:6 月 30 日 Ecma 大会批准 ECMA-262 第 17 版,7 个新特性全是标准库补强(getOrInsertIterator.concat、原生 Base64、Array.fromAsync……),详解见下文
  • Temporal 九年冲线:3 月终于达到 Stage 4,可惜错过 ES2026 截止、排进了 ES2027;好消息是 Firefox 和 Chrome 都已经能用了,前瞻见下文
  • Decorators 罕见降级:苦等四年没等来浏览器原生实装,5 月从 Stage 3 被打回 2.7;同期 Records & Tuples 正式撤回,提案大事记见下文
  • Ecma 会员大洗牌:NVIDIA、AMD 等硬件巨头集体入会,字节跳动退出,会员总数 92 家创新高,成员动态见下文
  • 一个冷知识:Ecma 在 2025 年 12 月发布了一整套 NLIP 标准,AI Agent 的"自然语言交互"也开始标准化了

作为前端开发工程师,ES6 这个词想必不陌生,ECMAScript 这个奇怪发音的名字应该也应该有所了解,你是否好奇过 ECMA 世界的神秘数字代号,ECMA-262 是什么,ESxxx 又是什么,TC39 是什么,Stage 3 、Stage 4 又意味着什么?你是否被层出不穷的 ES20XX 新特性所迷惑,需要掌握该特性到底是哪年推出的吗,这些提案在哪里能够看到,哪些已经可用,历年的 ES 标准去哪里查找?今天我来带大家揭开 ECMAScript 的神秘面纱,彻底理解掌握这些神秘代号,以及截止到 2026 年 ECMAScript 的特性。

另:祝贺我国首个 JS 语言提案在 2021 年 4 月进入 Stage 3,在 2021 年 11 月成功进入 Stage 4,并在 ECMAScript 2022 正式发布,成为事实上的标准,详见 Error Cause

2026 年 6 月 30 日,Ecma 国际第 131 届大会在日内瓦通过了 ECMA-262 第 17 版 —— ECMAScript® 2026 标准,同场会议还通过了 ECMA-402 第 13 版(ECMAScript 国际化 API)。规范全文可在 tc39.es/ecma262/202… 在线阅读。

ECMAScript 历史

我们首先来看 ECMA 是什么。ECMA,读音类似“艾克妈”,是欧洲计算机制造商协会(European Computer Manufacturers Association)的简称,是一家国际性会员制度的信息和电信标准组织。1994 年之后,由于组织的标准牵涉到很多其他国家,为了体现其国际性,更名为 Ecma 国际(Ecma International),因此 Ecma 就不再是首字母缩略字了。

img-01.png 了解了这段历史,为了技术写作的专业性,如果文章中提到 Ecma 的时候,规范写法是 Ecma(官方 logo 用小写 ecma),不要写成全大写 ECMA,除非是 ECMAScript 或 ECMA-262 这类专有名词与标准编号。

1995 年,著名的网景公司(Netscape)的 Brendan Eich 开发了一种脚本语言,最初命名为 Mocha,后来改名为 LiveScript,最后为了蹭当时火热的 Java 热度重命名为了 JavaScript。

了解了 Ecma 国际和 JavaScript,就方便了解 ECMAScript 了,ECMAScript 是一种由 Ecma 国际在标准 ECMA-262 中定义的 脚本语言 规范。这种语言往往被称为 JavaScriptJScript(微软在 IE 时代的方言,已成历史),但实际上它们是 ECMA-262 标准的实现和扩展。

神秘的 ECMA-262

上文提到了第一个神秘代码 ECMA-262,ECMA-262 到底是什么呢?原来 Ecma 国际的标准,都以"ECMA-编号"命名(标准编号保留历史上的全大写写法),ECMA-262 就是第 262 号标准,具体就是指 ECMAScript 遵照的标准。1996 年 11 月,网景公司将 JavaScript 提交给 Ecma 国际进行标准化。ECMA-262 的第一个版本于 1997 年 6 月被 Ecma 国际采纳。

尽管 JavaScript 和 JScript 与 ECMAScript 兼容,但包含超出 ECMAScript 的功能。

我们如何查看最新最全的 Ecma 标准呢,可以查看 Ecma 国际官网的 Standards。截止到 2026 年 7 月,最新的 Ecma 标准已经到了 ECMA-434。有意思的是,ECMA-430 ~ 434 是 2025 年 12 月批准的一整套 NLIP(Natural Language Interaction Protocol,自然语言交互协议)标准及其安全配置与传输绑定,AI Agent 时代,连"自然语言交互"本身都开始标准化了。同批还有 ECMA-429(Minimum common web API,为各类 JS 运行时定义最小通用 Web API 集)。

img-02.png Ecma 标准涉及的类别非常多,官网因此提供了按照类别和最新修改排序的功能,我们来看看 ECMA-262 属于哪个类别:

img-03.png ECMA-262 属于“软件工程与接口”类别,该类别一共有 22 个标准,详见上图(2025 年 12 月新增的 ECMA-427、428、429 分别是 Package-URL 规范、通用生命周期枚举 CLE 和 Minimum common web API;NLIP 系列不在此类别)。注意,ECMA-262 的最新更新日期是 2026 年 6 月,当前最新的标准就是 ES2026。

探秘 Ecma TC39 神秘组织

揭开了 Ecma-262 神秘面纱之后,我们来探秘一个代号名为 TC39 的神秘组织。

img-04.png 其实官网解释的已经很清楚了,我用中文简要概括下:

TC39 是 Technical Committee 39 的简称,是制定 ECMAScript 标准的委员会,由 Ecma 会员单位派出的代表组成:浏览器厂商是核心,但金融公司、开源咨询公司、高校的代表也在其中(后文延伸阅读会细说)。主席团三人分别来自 IBM、Bloomberg 和 Igalia(2026 年现任),下设 5 个工作组(Task Groups):

  • TC39-TG1(通用 ECMAScript® 语言,包括语法、语义、类库以及支持该语言的技术)
  • TC39-TG2(ECMAScript® 国际化 API 标准)
  • TC39-TG3(安全)
  • TC39-TG4(Source map 标准)
  • TC39-TG5 (编程语言标准化实验)

我们经常会看到类似的新闻:XX 公司成为 Ecma TC39 成员。想要以成员身份参加 TC39 会议,必须先加入 Ecma(Ecma 官网改版后,这段参与指引移到了 TC39 官网首页,顺带把六阶段流程、会议纪要的入口也放在了一起):

img-05.png 那 Ecma 到底有哪些成员呢?Ecma 官网给出了答案:

img-06.png 几大巨头赫然在列!2026 年的 6 家正式会员:Apple、Bloomberg、Google、华为、IBM、Meta。这里划重点澄清一个常见误解(包括本文早期版本也没写严谨):会员身份只有一种,就是 Ecma 会员,不存在单独的"TC39 会员"。Ecma 会员一共有 5 种类别,分别是正式会员(Ordinary members)、准会员(Associate members)、中小企业会员(SME members)、小型私营公司会员(SPC members)、非营利组织会员(NFP members);会费交给 Ecma 之后,参加 TC39、TC54 等任意技术委员会都不再额外收费,只是参加 TC39 还要多签一份专利免版税协议(RFTC 注册表,不花钱)。我们来看正式会员和准会员的对比:

img-07.png 准会员没有 Ecma 大会(General Assembly)的投票权!在准会员中,我国还有 2 家:阿里巴巴、360(对比 2021 年减少了腾讯;字节跳动曾在 2021-2025 年间在列,2026 年已退出会员名单)。

Wait,CHF 70000,这是 70000 法郎?Ecma 果然是欧洲豪门,正式会员年费约 59 万人民币(按 2026 年 7 月汇率 1 CHF ≈ 8.4 CNY)。算了一下,Ecma 国际会员费收入每年就有 1,260,000 法郎,破了千万人民币大关。

img-08.png 了解更多关于 TC39 的内容,可以探索其官网 TC39 – Specifying JavaScript. 和 GitHub 仓库 Ecma TC39 · GitHub注意这个仓库很重要。查看一下 members,发现了 月影李松峰元彦 三位国内大佬。

Ecma 会员最新动态(2026 年)

截至 2026 年 7 月(Ecma 会员页),会员格局有几个值得注意的变化:

  • 正式会员(Ordinary members)6 家:Apple、Bloomberg、Google、华为、IBM、Meta,华为继续保持我国唯一正式会员身份
  • 中国企业变动:阿里巴巴、360 继续保持准会员;字节跳动已退出会员名单(2025 年还在准会员之列);Sujitech(Mask Network)仍为小型私营公司会员
  • 准会员阵容大扩容:NVIDIA、AMD、Oracle、Salesforce、ServiceNow、Shopify、Sony Interactive Entertainment、JetBrains、Dell、日立、Lockheed Martin、F5、Consensys、Functional Software(Sentry)等相继在列,这两年最显眼的变化就是硬件/AI 厂商与企业软件大厂集体入场
  • SME 会员:Igalia、Vercel 之外,新增 HeroDevs(专注开源软件 EOL 长期维护)
  • 非营利会员(NFP)达 51 家:Mozilla、Apache 软件基金会、OpenJS 基金会、OWASP 等

会员总数已从 2021 年的约 70 个、2025 年的 86 个增长到 92 个。等等,做显卡的 NVIDIA、AMD 跑来 JavaScript 标准组织干什么?字节跳动又为什么悄悄走了?往下看延伸阅读。

延伸阅读:巨头们到底是来干嘛的?

为了回答上面两个问题,我让 Claude 的研究 Agent 把 Ecma 的年鉴(Memento,每年公开一版,逐个委员会列出注册代表名单)和 TC39 的公开会议纪要翻了一遍——90 多次检索、逐条要求给出一手来源,这种苦力考据活正是 Agent 的强项。答案比想象的有意思。

先纠正一个直觉:Ecma ≠ TC39。 这几年 Ecma 悄悄开了好几张新牌桌,新会员各有各的座位:

  • TC54(软件供应链透明):2023 年 12 月成立,起因是 OWASP 把 SBOM 事实标准 CycloneDX 捐给 Ecma 做标准化(现为 ECMA-424),委员会主席正是 CycloneDX 创始人、ServiceNow 的 Steve Springett。洛克希德·马丁的 4 名注册代表全部坐在这一桌,Socket、IBM、Google、Apple、Apache 也在。背后的推手是欧盟《网络弹性法案》(CRA):2026 年 9 月起漏洞报告义务生效、2027 年 12 月全面强制,在欧盟卖软件就得交机器可读的 SBOM,OWASP 官方直接把 TC54 标准化和 CRA 合规挂上了钩。一句话:合规压力把企业软件大厂推进了标准会议室
  • TC55(Web 互操作服务器运行时):就是社区组织 WinterCG 转正的 WinterTC,主席是 Deno 的 Luca Casonato,Cloudflare、Vercel、Shopify、阿里都在参与,2025 年 12 月刚产出第一个标准 ECMA-429(Minimum Common Web API)。
  • TC56(NLIP,AI Agent 自然语言交互协议):IBM 牵头(主席 Dinesh Verma),ServiceNow、日立、微软和一票大学在列,2025 年 12 月一口气通过了 ECMA-430 ~ 434 五连发
  • TC57(HLSL 着色器语言):2026 年 2 月,微软官宣把 DirectX 的 HLSL 交给 Ecma 做厂商中立标准化,公告里特意写了"平台方可以平等参与"。四个月后的第一次大会,NVIDIA 和 AMD 双双入会。两家都没说来意(Ecma 公告和自家博客都只字未提),但时间点摆在这里,大概率是奔着"给 GPU 语言投票"来的,而不是 JavaScript——这一条属于合理推测,等 2027 年年鉴的委员会名单揭晓。

所以第一个问题的答案揭晓:显卡厂确实坐进了 Ecma 的会议室,但多半不是 TC39 那间。顺便分享两个翻年鉴翻出来的彩蛋:戴尔早在 2019 年就入会了,注册代表在 TC26 声学委员会当副主席,专门研究小风扇噪音,和 JS 半毛钱关系没有;而 F5 的会籍是 2020 年收购 Shape Security 继承来的,ES2026 里一人贡献两个特性的 Kevin Gibbons,工牌就是 F5 的。

再看退场的

字节跳动 2021 年 6 月入会时,TC39 秘书长在会议纪要里留下过一句相当直白的记录:"Honestly speaking I have not heard about them(老实说,我没听说过这家公司)"。之后四年,字节在年鉴里注册过 8 名代表,但 Agent 把 2021-2026 年的全部 TC39 公开纪要整仓检索了一遍:零发言、零提案、零签到记录。会籍在 2025 年底到期后未续费(官网会员页快照 2025 年 11 月还在、2026 年 1 月消失),无声离场。它真正的标准圈交集其实在 WinterCG(TC55 的社区前身,参与者名单里至今挂着 ByteDance),而它的 JS 引擎 PrimJS(Lynx 框架的运行时)只需要实现 ECMAScript,不需要会员身份。

这也不是孤例:腾讯 2020 年入会、2023 年退出,公开纪要里同样零命中。一句话总结:不到 30 万人民币的年费,买张桌边椅不难,难的是真派人来开会。对照另一边:阿里的 Error Cause 提案进了 ES2022,华为持有正式会员的大会投票权——中国公司在这张桌上的存在感,从来不是会费决定的。

顺便回答一个实用问题:官网能不能直接查"TC39 的成员名单"?最接近的页面是 TC39 专利免版税协议签署名单,但注意它是历史累计名单:签过就上榜,约 80 家,退会也不摘牌、只加个星号注明"前 Ecma 会员"——字节和腾讯至今都还挂在上面。想看当前真正给 TC39 注册了代表的公司,得翻每年的 Memento 年鉴。这份名单还提供了一个小佐证:NVIDIA 和 AMD 都没签这份 TC39 协议,侧面说明他们入会确实不是冲着 JavaScript 来的。

那反过来,真正在 TC39 干活的都是谁? 按 2026 年年鉴和提案记录拼一张速写:

  • 引擎方,握着事实上的否决权:Google(V8)、Apple(JavaScriptCore)、Mozilla(SpiderMonkey,以非营利会员身份在列)。有意思的是,微软如今只是准会员,正式会员六家里并没有它。
  • 主席团与编辑部:主席团来自 IBM、Bloomberg、Igalia;ES2026 规范的三位编辑,一位在 Google(Shu-yu Guo),另外两位都在 F5(Michael Ficarra、Kevin Gibbons)。
  • 最舍得花钱的:Bloomberg。一家华尔街终端公司,却常年出资把提案做成实现,Temporal 的工程落地就是它出钱、Igalia(SME 会员,西班牙开源咨询公司,TC39 的"雇佣军工程队")承接。
  • 提案高产户:看 ES2026 七个特性的作者雇主就够了:Mozilla(Upsert)、F5(Base64 和 sumPrecise 一家占俩)、Socket(Error.isError 的 Jordan Harband,圈内最高产的 champion 之一)。
  • 挂名彩蛋:Oracle 也在准会员名单里,但它在 JS 圈的存在感主要是握着 "JavaScript" 这个商标:Deno 2024 年底向美国专利商标局请愿注销,案子打到 2026 年中还没完。JavaScript 这个名字,至今不属于写 JavaScript 的人。

我们熟悉的 ES6

探究完神秘的 ECMA-262 和 TC39 之后,我们缓口气,来看看我们最为熟悉的 ESX 家族。

上文提到 ECMAScript 是由 Ecma 国际在标准 ECMA-262 中定义的脚本语言规范。到 2015 年,正式发布过 1、2、3、5、5.1、6 共 6 个版本(第 4 版胎死腹中、从未发布,版本号就此空缺,这段公案见下文的 ES6 元年特辑)。

我们常把第 5 版和 5.1 修订版统称做 ES5,将第 6 版及其后的版本统称做 ES6(因为从 2015 年起,ECMAScript 终于步入正轨,每年发布一次版本,为了应对每年递增的版本,用变革了 JavaScript 时代的 ES6 作为后续版本的代称)。

划重点,Web 前端招聘的 JD 中,经常出现的 ES6,不仅仅是 ES2015 这个版本,而是指代 ES2015 和其后每年发布的 ECMAScript 版本

从 ECMAScript 第 6 版开始,每年发布一个 ECMAScript 版本,因此 ECMAScript 版本有了很多名字,包括全名 ECMAScript 6、简写 ES6、年份命名 ECMAScript 2015、年份简写 ES2015。最常见的名字还是 ES6,之后推出的 ES7、ES8 等同理。注意 ES6 之后的版本基本上按照年份简称,ES7、ES8 这种简称不常用。

img-09.png 需要注意的是,自从 TC39 进程 制定以来,ECMAScript 版本的重要性就降低了很多。大家不必记住某一个 ES 特性到底是哪年推出的。现在真正重要的是提案处于哪个阶段:一旦提案到了第 4 阶段(Stage4),那么它就可以使用了。但是即使这样,你仍然需要检查你的引擎是否支持该功能。

这里又提到了一个 TC39 进程 和阶段(Stage)的概念,我们接下来看看这两个概念是什么含义。

TC39 进程和 Stage X

TC39 进程 顾名思义,肯定是 TC39 组织发布的一个进程。随着 ECMAScript 6 的发布,当时的发布流程出现了两个明显的问题:

  • 如果在两个 release 之间多次通过早已准备好的功能,势必在其 release 之前等待很长一段时间。而且功能准备如果很晚,会增加 deadline 之前匆忙赶工的风险。
  • 很多功能在其实现和使用之前就花了很长时间在设计上,发现与实现和使用相关的设计缺陷会非常晚。

为了解决上述问题, TC39 建立了新的 TC39 进程:

  • ECMAScript 功能设计与每年的 ECMAScript 版本发布独立,使用不同阶段(Stage)来区分功能的状态。2023 年 11 月后,新增 Stage 2.7,共有 6 个阶段,从 Stage 0(strawperson)开始,到 Stage 4(finished)结束。
  • 越往后的阶段,需要原型实现和真机测试,可以建立设计和实现之间的反馈机制。
  • ECMAScript 版本每年发布一次,发布的内容包含在 release deadline 之前的全部到达 Stage 4 的功能。

TC39 进程的演进历史

2023 年 11 月后的新 6 阶段流程

img-10.png

2015-2023 年的经典 5 阶段流程

img-11.png

  • Stage 0:代号“稻草人(strawman)”,草案阶段
  • Stage 1:代号“提案(proposal)”, TC39 帮助阶段
  • Stage 2:代号“草案(draft)”, 本阶段很有可能成为标准
  • Stage 3:代号“候选(candidate)”, 已完成,需要从实现中获得反馈
  • Stage 4:代号“结束(finished)”, 准备成为标准

为什么要增加 Stage 2.7?

2023 年 11 月 30 日,TC39 委员会决定在流程中增加 Stage 2.7,主要基于以下考虑:

  1. 分离关注点:将"规范完成"(Stage 2)和"测试编写"(Stage 2.7)分离,让每个阶段的目标更加明确
  2. 提高确定性:当提案到达 Stage 2.7 时,规范已经冻结,开发者可以更有信心地开始试用
  3. 优化审核流程:审核者(reviewers)需要在 Stage 2.7 之前完成签署,避免了后期的反复修改

关于为什么选择 2.7 这个数字,TC39 给出了有趣的解释:

  • 不重新编号是为了避免让历史文档变得难以理解
  • 选择 .7 而非 .5 是因为这个阶段更接近 Stage 3
  • 不使用 3a/3b 是为了避免混淆

我国提案的里程碑

理解了 Stage 各阶段的含义,就能理解我国首个 JS 语言提案在 ECMA 进入 Stage 3 这个新闻的意义了。2021 年 4 月,由阿里巴巴前端标准化小组与淘系技术提出的 Error Cause 提案进入 Stage 3,这意味着:

  • 提案规范已经完成,不会有大的改动
  • JavaScript 引擎开始实验性实现
  • 这是中国首个推进到如此高阶段的 ECMAScript 提案
  • 该提案最终在 ES2022 中正式成为标准(Stage 4)

如何跟踪提案进展?

想要了解各个提案的最新状态,可以访问以下资源:

  1. TC39 Proposals - 查看所有提案的当前阶段
  2. TC39 ECMA262 - ECMAScript 规范的官方仓库
  3. TC39 Meeting Notes - TC39 会议记录,了解提案讨论细节

💡 开发者建议:从 ES2016 开始,不要再以"这个浏览器支持 ES20XX 吗?"的方式思考,而应该关注具体特性:"这个特性到达 Stage 4 了吗?目标环境支持吗?"这种思维方式更符合现代 JavaScript 的发展模式。

历届 ES 特性全收录(ES2026 → ES2015)

网上有太多零散的 ES 特性总结,很多同学想知道,有官方的 ECMAScript 功能列表吗

当然有,TC39 仓库列出了 已完成提案 以及它们的版本。自 2015 年 ES6 发布以来的 11 年间,截至 2026 年 7 月,该列表共收录 78 个条目(其中 Class Fields 一条合并了 3 个提案),另有 4 个提案已达 Stage 4、将随 ES2027 发布(详见下一章)。

本章按时间降序排列:最新的 ES2026 放最前面,一路回溯到 2015 年的 ES6 元年,想查哪年翻哪年。逐年下潜之前,我们先看全景。

一表看完 12 个版本

版本发布ECMA-262特性数代表特性一句话主题
ES20262026-06第 17 版7getOrInsertIterator.concat、原生 Base64标准库补口
ES20252025-06第 16 版10Iterator Helpers、Set 集合运算、RegExp.escape迭代器与正则大年
ES20242024-06第 15 版7Object.groupByPromise.withResolvers、RegExp v分组与并发工具
ES20232023-06第 14 版4findLasttoSorted 等不变式方法数组不可变化
ES20222022-06第 13 版8Class Fields、Top-level await.at()、Error CauseClass 成熟 + 我国首提案
ES20212021-06第 12 版5replaceAllPromise.any、逻辑赋值小而美
ES20202020-06第 11 版9可选链 ?.、空值合并 ??、BigInt、import()语法高光年
ES20192019-06第 10 版8flat / flatMapObject.fromEntries数组对象补全
ES20182018-06第 9 版8异步迭代、对象 rest/spread、正则四件套异步迭代 + 正则大年
ES20172017-06第 8 版6async/awaitObject.entries、共享内存async/await 元年
ES20162016-06第 7 版2includes** 运算符最小可行发布
ES20152015-06第 6 版20+Class、模块、箭头函数、Promise、let / const语法大爆炸

特性数量趋势

img-21.png 把这 11 年 78 个条目摊开,能看出三条明显的线:

  1. 语法在退场,标准库在进场。上一个改变书写方式的大语法还是 ES2022 的 Class Fields(下一个要等 ES2027 的 using),而 ES2026 的 7 个特性清一色是 API。语言骨架已经定型,现在补的是血肉。
  2. "规范发布"越来越像"追认既成事实"。Stage 4 要求两个引擎实装加 test262 测试通过,于是特性普遍先能用、后进标准:Array.fromAsync 2023 年就能在三大浏览器使用,2026 年才写进正文;Temporal 更是等了 9 年。所以别问"浏览器支持 ES2026 吗",要问"这个特性到 Stage 4 了吗"。
  3. 迭代器成为第一公民。ES2025 的 Iterator Helpers、ES2026 的 concat、ES2027 的 zip,再加上排队中的 chunking / includes / join,TC39 正在把十年前 ES6 埋下的迭代器协议,一口气兑现成全家桶。

好,下面从最新的 ES2026 开始,逐年下潜。

ES2026 新特性

2026 年 6 月 30 日随 ECMA-262 第 17 版正式发布(TC39 在 2026 年 3 月会议就批准了候选规范,Ecma 大会只是走完最后流程),共包含 7 个新特性。如果说 ES2025 的主题是"迭代器和正则",那 ES2026 的主题就是补齐标准库的高频缺口:没有语法层面的大动作,但每一个都在消灭一段你写过无数遍的样板代码。

先来一张全家福:

#特性一句话总结Stage 4 时间
1Upsert(getOrInsert)Map 取值,没有就插入默认值,一步到位2026-01
2JSON.parse source text accessreviver 可拿到原始文本,大整数精度不再丢失2025-11
3Iterator SequencingIterator.concat 惰性串接多个迭代器2025-11
4Uint8Array to/from Base64二进制 ↔ Base64/Hex 原生互转,告别 atob2025-07
5Math.sumPrecise无累积误差的浮点求和2025-07
6Error.isError跨 realm 可靠判断真 Error2025-05
7Array.fromAsyncArray.from 的异步版2025-05

本节兼容性数据截至 2026 年 7 月,来自 MDN BCD 并经部分实测校验;Bun 数据为 Bun 1.3.14 实测。

下面我们逐个拆开看。

  1. Upsert(Map/WeakMap.prototype.getOrInsert / getOrInsertComputed)
  • 作者: Daniel Minor(Mozilla)、Lauritz Thoresen Angeltveit 等(挪威卑尔根大学 University of Bergen 的学生团队深度参与,TC39 校企合作的一段佳话)
  • 维护者: Daniel Minor
  • TC39 会议记录: 2026 年 1 月(赶上 ES2026 末班车的特性)
  • 说明: 为 Map 和 WeakMap 添加"取值,键不存在则先插入再返回"的原子化方法
  • 解决的核心问题:消灭 hassetget 三连样板代码,这是用 Map 做分组、计数、缓存时逃不掉的模式。
// ❌ 之前:三行样板,写过 Map 分组的人都懂
if (!groups.has(user.dept)) {
  groups.set(user.dept, []);
}
groups.get(user.dept).push(user);

// ✅ ES2026:一步到位
groups.getOrInsertComputed(user.dept, () => []).push(user);

// 计数器场景用 getOrInsert 给默认值
counts.set(word, counts.getOrInsert(word, 0) + 1);
  • 为什么重要
    • 🎯 两个方法各司其职getOrInsert(key, default) 直接给默认值;getOrInsertComputed(key, cb) 只在键缺席时才调用工厂函数,避免无谓的对象构造开销
    • 🌍 语言对齐:对标 Python 的 setdefault、Rust 的 entry().or_insert(),JavaScript 终于补上这一课
    • 📚 Map 和 WeakMap 同时获得,缓存 / memoization 场景(WeakMap 键为对象)同样受益
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
14514426.226+2.6.7
  1. JSON.parse source text access
  • 作者: Richard Gibson
  • 维护者: Richard Gibson
  • TC39 会议记录: 2025 年 11 月
  • 说明: JSON.parse 的 reviver 新增第三个参数以访问原始源文本;配套新增 JSON.rawJSON() / JSON.isRawJSON() 控制序列化输出
  • 解决的核心问题:JSON 数字精度丢失这一经典痛点:后端返回 int64 ID 或高精度金额,JSON.parse 一过手就变成损失精度的 Number。
// ❌ 之前:大整数 ID 解析即损坏
const txt = '{"id": 9007199254740993}';
JSON.parse(txt).id;      // 9007199254740992 —— 悄悄丢了 1

// ✅ ES2026:reviver 拿到原文,转 BigInt 不过 Number 的手
const obj = JSON.parse(txt, (key, val, { source }) =>
  key === 'id' ? BigInt(source) : val
);
obj.id;                  // 9007199254740993n ✓

// 序列化侧:rawJSON 让大整数原样输出
JSON.stringify({ id: JSON.rawJSON('9007199254740993') });
// '{"id":9007199254740993}'
  • 为什么重要
    • 💰 金融/ID 场景刚需:以前只能靠正则预处理 JSON 文本或让后端把 int64 改成字符串,现在标准内解决
    • 🔒 只对原始值生效context.source 仅在解析 number/string/boolean/null 时提供,对象和数组没有(避免巨大字符串驻留)
    • 🧩 为 Decimal 提案铺路:未来十进制数类型的 JSON 互操作靠它打底
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
11413518.4211.33
  1. Iterator Sequencing(Iterator.concat)
  • 作者: Michael Ficarra
  • 维护者: Michael Ficarra
  • TC39 会议记录: 2025 年 11 月
  • 说明: 新增静态方法 Iterator.concat(...items),把多个可迭代对象按顺序串接成一个迭代器
  • 解决的核心问题:串接多个数据源时,[...a, ...b] 需要先把所有元素物化成数组(无限序列直接爆炸),手写 generator yield* 又太啰嗦。
// ❌ 之前:要么物化数组,要么手写 generator
const merged = [...map.keys(), ...someSet, 'tail']; // 全部展开,内存浪费
function* concat(...its) {                          // 或者八行样板
  for (const it of its) yield* it;
}

// ✅ ES2026:惰性串接,还能继续链式调用
const merged = Iterator.concat(map.keys(), someSet, ['tail']);
for (const x of merged.filter(v => v !== null).take(10)) {
  // 惰性求值:不会预先展开任何一个数据源
}
  • 为什么重要
    • 🔗 ES2025 Iterator Helpers 的直系补充:返回的同样是 Iterator Helper 对象,map / filter / take 随便接
    • ♾️ 无限序列友好:惰性消费,串接生成器毫无压力
    • 🚧 严格性:参数必须是可迭代对象,传原始值直接 TypeError,避免静默 bug
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
14614726.426+2.7.2
  1. Uint8Array to/from Base64(含 Hex)
  • 作者: Kevin Gibbons
  • 维护者: Kevin Gibbons
  • TC39 会议记录: 2025 年 7 月
  • 说明: 为 Uint8Array 添加 Base64 / Hex 编解码方法:静态的 fromBase64 / fromHex、实例的 toBase64 / toHex,以及面向流式场景的 setFromBase64 / setFromHex
  • 解决的核心问题:JavaScript 居然一直没有"二进制 ↔ Base64"的标准 API。atob / btoa 操作的是"二进制字符串"这个上古概念,不支持 url-safe 字母表,处理真正的二进制数据还要手动逐字节转换。
// ❌ 之前:atob 迂回三步走
const binStr = atob('SGVsbG8gV29ybGQ=');
const bytes = Uint8Array.from(binStr, (c) => c.charCodeAt(0));

// ✅ ES2026:直达
const bytes = Uint8Array.fromBase64('SGVsbG8gV29ybGQ=');
new TextDecoder().decode(bytes);  // 'Hello World'

// url-safe、免 padding、Hex 全都原生支持
bytes.toBase64({ alphabet: 'base64url', omitPadding: true });
Uint8Array.fromHex('deadbeef');   // Uint8Array [222, 173, 190, 239]

// 流式解码:只消费完整的 4 字符块,剩余部分留给下一轮
const buf = new Uint8Array(1024);
const { read, written } = buf.setFromBase64(chunk, {
  lastChunkHandling: 'stop-before-partial',
});
  • 为什么重要
    • 🔐 WebCrypto / JWT / 图片 dataURL 场景高频:密钥、签名、二进制附件的编解码不再依赖第三方库或 hack
    • 引擎原生实现:比 JS 手写快一个量级,setFrom* 系列还支持 buffer 复用与背压
    • 🎛️ 选项齐全alphabet(base64/base64url)、lastChunkHandling(loose/strict/stop-before-partial)、omitPadding
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
14013318.2252.5.0
  1. Math.sumPrecise
  • 作者: Kevin Gibbons
  • 维护者: Kevin Gibbons
  • TC39 会议记录: 2025 年 7 月
  • 说明: 对一个 Number 可迭代对象做"仿佛以无限精度计算、最后只舍入一次"的求和
  • 解决的核心问题:朴素的 reduce((a, b) => a + b) 每一步都要舍入到 float64,误差会累积,量级悬殊时小数直接被"吞掉"。
const xs = [1e20, 0.1, -1e20];

// ❌ 之前:0.1 被 1e20 吞掉了
xs.reduce((a, b) => a + b, 0);  // 0

// ✅ ES2026:数学意义上的正确答案
Math.sumPrecise(xs);            // 0.1

// 两个容易踩的细节
Math.sumPrecise([]);            // -0(不是 0)
Math.sumPrecise([1, '2']);      // TypeError!拒绝隐式转换
  • 为什么重要
    • 📊 统计/科学计算/财务汇总的正确性保障:实现层面通常采用 Shewchuk 算法,社区同类库(如 Python 的 math.fsum)早已验证需求
    • 🚫 刻意从严的 API:只接受可迭代对象(不是 rest 参数)、遇到非 Number 直接抛错,把错误暴露在开发期
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
14713726.2❌ 尚未支持2.7.8
  1. Error.isError
  • 作者: Jordan Harband
  • 维护者: Jordan Harband
  • TC39 会议记录: 2025 年 5 月
  • 说明: 通过内部槽 [[ErrorData]] 的品牌检查,可靠判断一个值是否为真正的 Error 对象
  • 解决的核心问题instanceof Error 在跨 realm 场景(iframe、Worker 消息、Node 的 vm 模块)会失效,因为不同 realm 各有一套 Error.prototype;而鸭子类型检查又能被伪造对象轻松骗过。
// ❌ 之前:跨 realm 的 Error 认不出来
const vm = require('node:vm');
const err = vm.runInNewContext('new Error("boom")');
err instanceof Error;   // false —— 原型链来自另一个 realm

// ✅ ES2026:品牌检查,不看原型链
Error.isError(err);     // true

Error.isError({ name: 'Error', message: '', stack: '' }); // false,防伪造
Error.isError(new DOMException('x'));                     // true,DOMException 也算
  • 为什么重要
    • 🛡️ 库作者的刚需:错误上报 SDK、序列化库、断言库终于有了可靠的判别手段,对标 Array.isArray() 补齐语言一致性
    • 🕰️ 陈年提案翻案:最早可追溯到 2016 年,搁置多年后 2024 年由 Jordan Harband 复活推动,一年内光速定稿
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
13413818.424.32.2
  1. Array.fromAsync
  • 作者: J.S. Choi
  • 维护者: J.S. Choi
  • TC39 会议记录: 2025 年 5 月
  • 说明: Array.from 的异步版本:消费异步可迭代对象(或元素为 Promise 的同步可迭代对象),返回 Promise<Array>,支持可选的(可异步)mapFn
  • 解决的核心问题for await...of + 手动 push 这段样板代码的表达式化。
// ❌ 之前:四行样板
const chunks = [];
for await (const chunk of stream) {
  chunks.push(chunk);
}

// ✅ ES2026:一行
const chunks = await Array.fromAsync(stream);

// 配合 async generator 收集分页数据
async function* paginate(url) {
  while (url) {
    const r = await (await fetch(url)).json();
    yield* r.items;
    url = r.next;
  }
}
const ids = await Array.fromAsync(paginate('/api/list'), (item) => item.id);
  • 为什么重要
    • 🌊 串行消费、尊重背压:与 Promise.all(并发等待既有的一组 Promise)语义互补,处理流时不会把生产者压垮
    • 🐢 Stage 3 等了近三年(2022-09 达 Stage 3,等待第二个引擎实现),所以它反而是 ES2026 七兄弟里浏览器落地最早的:Safari 16.4 / Firefox 115 / Chrome 121 早就可用
  • 兼容性
ChromeFirefoxSafariNode.jsDenoBun
12111516.4221.38

ES2025

2025 年 6 月 25 日正式发布,包含以下新特性:

  1. RegExp.escape
  • 作者: Domenic Denicola、Benjamin Gruenbaum、Jordan Harband
  • 维护者: Jordan Harband、Kevin Gibbons
  • TC39 会议记录: 2025 年 2 月
  • 说明: 提供一个静态方法来转义字符串中的特殊正则字符
  • 解决的核心问题:将普通字符串安全地用在正则表达式中,避免特殊字符被误解释。
// ❌ 之前:手动转义容易遗漏
const userInput = "price: $9.99";
const pattern = new RegExp(userInput); // 💥 $ 和 . 会被当作特殊字符
// ✅ ES2025:标准化的安全转义
const escaped = RegExp.escape("price: $9.99");
// 返回: "price:\\x20\\$9\\.99"
const safePattern = new RegExp(escaped); // 正确匹配字面字符串
  • 为什么重要
    • 🔥 社区呼声极高:npm 上 escape-string-regexp 包周下载量超 1 亿次
    • 🌍 国际标准对齐:JavaScript 终于拥有了其他语言早在 20 年前就有的功能(Python re.escape()、Ruby Regexp.escape() 等)
    • 🛡️ 安全保障:避免用户输入导致的正则表达式注入漏洞
  • 典型应用场景// 搜索高亮 function highlight(text, term) { const pattern = new RegExp((RegExp.escape(term)),gi);returntext.replace(pattern,<mark>{RegExp.escape(term)})`, 'gi'); return text.replace(pattern, '<mark>1'); }

// 动态替换 function replaceAll(text, find, replace) { const pattern = new RegExp(RegExp.escape(find), 'g'); return text.replace(pattern, replace); } `

  • 提案历程:这个提案从 2015 年开始讨论,历经 10 年终于在 2025 年 2 月达到 Stage 4,成为 ES2025 的一部分。提案仓库已于 2025 年 2 月 18 日归档,标志着这个功能正式定稿。
  • 兼容性

img-12.png

  1. Float16 on TypedArrays, DataView, Math.f16round
  • 作者: Leo Balter
  • 维护者: Leo Balter、Kevin Gibbons
  • TC39 会议记录: 2025 年 2 月
  • 说明: 添加 Float16Array 类型数组和相关的 DataView 方法,以及 Math.f16round
  • 核心价值:为 JavaScript 引入 16 位浮点数(半精度)支持,主要服务于 AI / 机器学习和图形处理场景 `// 新的 TypedArray 类型 const float16 = new Float16Array([1.0, 2.5, 3.14159]);

// 内存效率对比 const float32Array = new Float32Array(1000); // 4000 字节 const float16Array = new Float16Array(1000); // 2000 字节(节省50%)

// Math.f16round - 舍入到16位精度 Math.f16round(3.14159); // 3.140625 Math.f16round(65504); // 65504(最大值) Math.f16round(65505); // Infinity

// DataView 支持 const buffer = new ArrayBuffer(2); const view = new DataView(buffer); view.setFloat16(0, 3.14); console.log(view.getFloat16(0)); // 3.140625 `

  • 为什么重要
    • 🤖 AI/ML 优化:大多数神经网络推理可以使用 float16 而不损失精度,内存占用减半
    • 🎮 图形处理:WebGL 和 WebGPU 原生支持 float16,现在 JavaScript 可以直接操作
    • 💾 内存效率:处理大规模数值数据时显著降低内存占用
  • 实际应用场景: `// AI 模型权重存储 async function loadModelWeights(url) { const response = await fetch(url); const buffer = await response.arrayBuffer(); // 使用 Float16Array 加载模型权重,节省50%内存 return new Float16Array(buffer); }

// 图像处理中的颜色值 function processHDRImage(pixelData) { // HDR 图像使用 float16 存储颜色值 const float16Pixels = new Float16Array(pixelData); // 处理像素数据... }

// 与 WebGPU 交互 const gpuBuffer = device.createBuffer({ size: float16Array.byteLength, usage: GPUBufferUsage.VERTEX, mappedAtCreation: true }); new Float16Array(gpuBuffer.getMappedRange()).set(float16Array); `

  • 提案历程:Float16Array 提案响应了 Web 平台对高效数值计算的需求,特别是随着 WebGPU 和 AI 应用在浏览器中的兴起。提案仓库于 2025 年 5 月 24 日归档,标志着这个功能正式定稿。
  • 兼容性

img-13.png

  1. Promise.try
  • 作者: Jordan Harband
  • 维护者: Jordan Harband
  • TC39 会议记录: 2024 年 10 月
  • 说明: 提供统一的方式来处理同步和异步函数
  • 解决的核心问题:优雅地将任何函数(同步或异步)包装成 Promise,同时保持同步执行的性能优势。 `// ❌ 之前的困境 // 方法1:简单但低效(强制异步) Promise.resolve().then(() => fn()); // fn 被推迟到下一个微任务

// 方法2:高效但繁琐 new Promise(resolve => resolve(fn())); // 同步执行但写法冗长

// ✅ ES2025:简洁且高效 Promise.try(() => fn()); // 同步执行,自动捕获错误

`

  • 为什么重要: • ⚡ 性能优化:函数可以同步执行,避免不必要的异步开销 • 🛡️ 统一错误处理:无论函数是否抛出异常,都能用 .catch() 处理 • 📦 社区验证p-try npm 包周下载量 4400 万次,总下载量 89 亿次
  • 实际应用场景: `// 1. 不确定函数是否异步 function processData(data) { return Promise.try(() => { // 可能是同步验证,也可能是异步API调用 return validateOrFetch(data); }).then(result => { console.log('处理成功:', result); }).catch(error => { console.error('处理失败:', error); }); }

// 2. 初始化流程的错误处理 Promise.try(() => { // 可能抛出异常的初始化代码 const config = JSON.parse(configString); return initializeApp(config); }).catch(error => { console.error('初始化失败:', error); showErrorUI(); });

// 3. 与 async/await 配合 async function main() { const result = await Promise.try(() => { // 同步代码也能享受 async/await 的错误处理 return complexCalculation(); }); }

`

  • 标准化进程:该提案已达到 Stage 4,仓库于 2024 年 10 月 9 日归档。作为 ES2025 的一部分,它填补了 Promise API 中长期存在的空白,让 JavaScript 的异步编程模型更加完整和一致
  • 生态影响:Bluebird、Q、when 等主流 Promise 库早已提供类似功能,ES2025 的标准化意味着开发者终于可以在原生环境中使用这个高频特性,减少对第三方库的依赖。
  • 兼容性

img-14.png

  1. Sync Iterator Helpers
  • 作者: Gus Caplan
  • 维护者: Michael Ficarra、Jonathan Keslin、Kevin Gibbons
  • TC39 会议记录: 2024 年 10 月
  • 说明: 为迭代器添加 map、filter、take、drop 等辅助方法
  • 解决的核心问题:为迭代器提供类似数组的链式操作方法,让迭代器和数组一样易用。 `// ❌ 之前:迭代器缺乏辅助方法 function* naturals() { let i = 0; while (true) yield i++; }

// 需要手动转换为数组才能使用 map/filter const squares = Array.from(naturals()) .slice(0, 10) // 危险!naturals() 是无限的 .map(x => x * x);

// ✅ ES2025:迭代器原生支持链式操作 const squares = naturals() .take(10) // 安全!惰性求值 .map(x => x * x) .toArray(); // [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

`

  • 核心特性一览
    • 转换方法: map(), filter(), flatMap()
    • 截取方法: take(), drop()
    • 聚合方法: reduce(), toArray()
    • 判断方法: some(), every(), find()
    • 副作用: forEach()
    • 静态方法: Iterator.from()
  • 为什么重要
    • 🚀 惰性求值:所有方法都是惰性的,只在需要时才消费迭代器
    • ♾️ 无限序列支持:可以安全地处理无限迭代器
    • 🔗 链式调用:提供流畅的函数式编程体验
    • 📚 跨语言一致性:对标 Rust、Python、C# 等语言的迭代器 API
  • 标准化进程:该提案已达到 Stage 4,仓库于 2024 年 10 月 8 日归档。这标志着 JavaScript 终于拥有了现代化的迭代器 API,填补了与 Rust、Python 等语言在迭代器处理能力上的差距。
  • 生态影响:Node.js 的 Readable streams 已经实现了该提案的全部功能。许多流行库如 lodash、itertools 的功能将可以用原生 API 替代,减少项目依赖。
  • 兼容性

img-15.png

  1. JSON Modules
  • 作者: Myles Borins、Sven Sauleau、Dan Clark、Daniel Ehrenberg
  • 维护者: Myles Borins、Sven Sauleau、Dan Clark、Daniel Ehrenberg
  • TC39 会议记录: 2024 年 10 月
  • 说明: 允许直接导入 JSON 文件作为模块
  • 解决的核心问题:安全且标准地导入 JSON 数据,防止 MIME 类型混淆导致的代码注入攻击。 `// ❌ 之前的困境 // 方法1:使用 fetch(运行时加载,需要额外解析) const response = await fetch('./config.json'); const data = await response.json();

// 方法2:依赖构建工具(非标准,不同工具行为不一) import data from './config.json'; // 需要 webpack/rollup 等支持

// 方法3:动态导入(不够直观) const module = await import('./config.json');

// ✅ ES2025:标准且安全 import data from './config.json' with { type: 'json' };

`

  • 为什么重要
    • 🔒 安全保障:通过显式 type: "json" 声明,防止服务器返回可执行代码
    • 📦 零依赖:不再需要构建工具或 polyfill 来导入 JSON
    • 🌍 跨平台一致:浏览器、Node.js、Deno 等环境行为统一
    • 编译时优化:静态导入允许更好的 tree shaking 和优化
  • 标准化进程
    • 2020年7月:从 Import Attributes 提案中分离
    • 2024年10月8日:与 Import Attributes 一起进入 Stage 4
    • 最初由 Microsoft 为 V8/Chromium 实现
    • Apple (Ryosuke Niwa) 和 Mozilla (Anne van Kesteren) 提出的安全考虑促成了当前设计
  • 生态影响
    • 构建工具简化:Webpack、Rollup、Vite 等可以使用标准语法
    • 类型系统支持:TypeScript 可以提供更好的类型推断
    • 工具链统一:ESLint、Prettier 等工具可以识别标准语法
    • 性能优化:允许更好的静态分析和 tree shaking
  • 兼容性

img-16.png

  1. Import Attributes
  • 作者: Myles Borins、Sven Sauleau、Dan Clark、Daniel Ehrenberg
  • 维护者: Sven Sauleau、Dan Clark、Daniel Ehrenberg、Nicolò Ribaudo
  • TC39 会议记录: 2024 年 10 月
  • 说明: 为模块导入语句添加内联语法,以传递模块说明符之外的更多信息,为 JSON、CSS、HTML 等非 JavaScript 模块类型提供基础设施
  • 解决的核心问题:提供安全、标准化的方式来指定模块类型和其他元数据,防止 MIME 类型混淆攻击。 `// ❌ 之前的困境 // 方法1:依赖文件扩展名(不可靠) import data from './config.json'; // 扩展名不能保证内容类型

// 方法2:依赖 MIME 类型(可被篡改) import styles from './styles.css'; // 服务器可能返回 JavaScript

// 方法3:使用 URL scheme(复杂且非标准) import data from 'json:./config.json'; // 伪协议方案

// ✅ ES2025:显式且安全 import data from './config.json' with { type: 'json' }; import styles from './styles.css' with { type: 'css' };

`

  • 为什么重要
    • 🔒 安全基础:为所有非 JavaScript 模块提供安全导入机制
    • 🏗️ 可扩展架构:不仅支持 type,还可扩展其他属性
    • 🌐 跨环境一致性:浏览器、Node.js、Deno 行为统一
    • ⚙️ 向后兼容:从 assertwith 的平滑过渡
  • 标准化进程
    • 2019-12:Stage 1 作为 "module attributes"
    • 2020-06:Stage 2 限制属性不能作为缓存键
    • 2020-09:Stage 3 改名 "import assertions",使用 assert 关键字
    • 2021-05 到 2022-02:Chrome、Node.js、Deno 实现并发布
    • 2023-01:因与 HTML 语义不兼容降回 Stage 2
    • 2023-03:改名 "import attributes",改回 with 关键字,重回 Stage 3
    • 2024-10:进入 Stage 4
  • 生态影响
    • 统一模块系统:为 Web 平台的多种资源类型提供统一导入机制
    • 安全性提升:明确的类型声明防止内容注入攻击
    • 工具链标准化:构建工具可以基于标准语法优化
    • 未来扩展性:为更多模块类型和属性预留空间
  • 兼容性

img-17.png

  1. RegExp Modifiers
  • 作者: Ron Buckton
  • 维护者: Ron Buckton
  • TC39 会议记录: 2024 年 10 月
  • 说明: 允许在正则表达式内部动态启用或禁用修饰符标志,提供更精细的模式控制
  • 解决的核心问题:在正则表达式的不同部分应用不同的标志设置,无需拆分成多个正则或使用复杂的变通方案。 `// ❌ 之前的困境 // 方法1:使用多个正则表达式 const re1 = /[a-z]/i; // 忽略大小写 const re2 = /[a-z]/; // 区分大小写 // 需要组合使用,逻辑复杂

// 方法2:动态构建正则 const pattern = '[a-z]'; const re = new RegExp(pattern, someCondition ? 'i' : '');

// 方法3:复杂的字符类 /[a-zA-Z][a-z]/ // 第一个字符不区分大小写,第二个区分

// ✅ ES2025:内联修饰符 /^a-z/i;//第二部分禁用i标志/(?i:[az])[az]/i; // 第二部分禁用 i 标志 /^(?i:[a-z])[a-z]/; // 第一部分启用 i 标志

`

  • 为什么重要
    • 🎯 精确控制:在正则表达式的特定部分应用不同的标志
    • 📝 配置友好:适用于 JSON 配置、语法高亮器等不能执行代码的场景
    • 🔧 减少复杂性:避免拆分正则或使用复杂的变通方案
    • 🌍 行业标准:与 Perl、PCRE、.NET 等主流正则引擎保持一致
  • 标准化进程
    • 2021-10-27:提议进入 Stage 1(通过)
    • 2021-12-15:进入 Stage 2(仅限自包含形式 (?i:...)
    • 2022-06-07:进入 Stage 3
    • 2024-10:进入 Stage 4
  • 生态影响
    • 解析器增强:语法高亮器、代码分析工具可以更精确地处理文本
    • 配置简化:TextMate grammars、JSON 配置可以使用更强大的模式
    • 正则可读性:减少需要拆分或动态构建的正则表达式
    • 跨语言一致性:与 Perl、Python、.NET 等语言的正则语法更接近
  • 兼容性

img-18.png

  1. New Set Methods
  • 作者: Michał Wadas、Sathya Gunasekaran、Kevin Gibbons
  • 维护者: Kevin Gibbons
  • TC39 会议记录: 2024 年 4 月
  • 说明: 为 JavaScript 的内置 Set 类添加集合运算方法,如 union、intersection、difference 等集合操作方法
  • 解决的核心问题:原生 Set 缺乏基本的集合运算操作,开发者需要手写复杂的逻辑或依赖第三方库。 `// ❌ 之前的困境 // 方法1:手写集合运算(繁琐易错) function intersection(setA, setB) { const result = new Set(); for (const elem of setA) { if (setB.has(elem)) { result.add(elem); } } return result; }

// 方法2:使用展开运算符和 filter(性能差) const intersection = new Set([...setA].filter(x => setB.has(x))); const union = new Set([...setA, ...setB]);

// 方法3:依赖第三方库 import { intersection, union } from 'lodash';

// ✅ ES2025:原生支持 setA.intersection(setB); setA.union(setB); setA.difference(setB);

`

  • 为什么重要
    • 🧮 数学完整性:Set 终于有了完整的集合运算能力
    • 性能优化:原生实现比 JavaScript 实现更高效
    • 🎯 代码简洁:不再需要繁琐的循环和临时数组
    • 🌍 语言对齐:与 Python、Ruby、Swift 等语言保持一致
  • 标准化进程
    • 2018-05:首次在 TC39 会议讨论
    • 2019-01:继续讨论细节
    • 2022-03:讨论如何扩展内置类型
    • 2023-07:关键设计决策
    • 2024-02:接近完成
    • 2024-04:进入 Stage 4
  • 生态影响
    • 减少依赖:不再需要 lodash、ramda 等库的集合操作
    • 性能提升:原生 C++ 实现比 JavaScript 实现更快
    • 代码可读性:集合操作语义更清晰
  • 兼容性

img-19.png

  1. Duplicate Named Capture Groups
  • 作者: Kevin Gibbons
  • 维护者: Kevin Gibbons
  • TC39 会议记录: 2024 年 4 月
  • 说明: 允许在正则表达式的不同分支中重复使用相同的捕获组名称
  • 解决的核心问题:匹配多种格式的文本时,无法为语义相同的部分使用相同的组名,导致代码冗余和处理复杂。 `// ❌ 之前的困境 // 方法1:使用不同的组名(语义不清) const dateRegex = /(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/; const match = str.match(dateRegex); const year = match.groups.year1 || match.groups.year2; // 需要手动合并

// 方法2:使用编号捕获组(可读性差) const dateRegex = /([0-9]{4})-[0-9]{2}|[0-9]{2}-([0-9]{4})/; const match = str.match(dateRegex); const year = match[1] || match[2];

// 方法3:使用多个正则(性能差) const regex1 = /(?[0-9]{4})-[0-9]{2}/; const regex2 = /[0-9]{2}-(?[0-9]{4})/; const match = str.match(regex1) || str.match(regex2);

// ✅ ES2025:允许重复命名 const dateRegex = /(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/; const match = str.match(dateRegex); const year = match.groups.year; // 直接访问,自动选择匹配的分支

`

  • 为什么重要
    • 🎯 语义一致:相同含义的捕获组使用相同名称
    • 📝 代码简洁:无需手动合并多个组的结果
    • 🔄 格式灵活:轻松处理多种输入格式
    • 🌍 语言对齐:与 .NET、Python、Perl 等语言保持一致
  • 标准化进程更新
    • 2022-07:达到 Stage 3
    • 2024-04:进入 Stage 4
  • 兼容性

img-20.png

  1. Redeclarable global eval-introduced vars
  • 作者: Shu-yu Guo(V8)
  • TC39 会议记录: 2025 年 2 月
  • 说明: 一个纯规范层面的修复,冷门到市面上的 ES2025 年度盘点几乎都不会提它。全局作用域下通过直接 eval("var x") 引入的变量本来就是可删除的(configurable),修复后也允许被后续的 let / const 重新声明,顺便删掉了全局环境记录里专门追踪这类变量的 [[VarNames]] 机制,降低引擎实现复杂度。对日常业务代码几乎无感,属于只有"全网最全"才会为凑齐全部 10 个提案而收录的规范角落知识 😄

ES2024

ES2023

  • Array find from last
    • 作者:Wenlu Wang
    • 维护者:Wenlu Wang、Daniel Rosenwasser
    • TC39 会议记录:June 2022
    • 发布时间:2023
  • Hashbang Grammar
    • 作者:Bradley Farias
    • 维护者:Bradley Farias
    • TC39 会议记录:July 2022
    • 发布时间:2023
  • Symbols as WeakMap keys
    • 作者:Daniel Ehrenberg、Richard Button、Robin Ricard、Leo Balter、Rick Waldron、Caridy Patiño
    • 维护者:Daniel Ehrenberg、Richard Button、Robin Ricard、Leo Balter、Rick Waldron、Caridy Patiño
    • TC39 会议记录:January 2023
    • 发布时间:2023
  • Change Array by Copy
    • 作者:Ashley Claymore、Robin Ricard
    • 维护者:Ashley Claymore、Robin Ricard
    • TC39 会议记录:March 2022
    • 发布时间:2023

ES2022

ES2021

  • String.prototype.replaceAll
    • 作者:Peter Marshall、Jakob Gruber、Mathias Bynens
    • 维护者:Mathias Bynens
    • TC39 会议记录: June 2020
    • 发布时间:2021
  • Promise.any
    • 作者:Mathias Bynens、Kevin Gibbons、Sergey Rubanov
    • 维护者:Mathias Bynens
    • TC39 会议记录: July 2020
    • 发布时间:2021
  • WeakRefs
    • 作者:Dean Tribble、Sathya Gunasekaran
    • 维护者:Dean Tribble、Mark Miller、Till Schneidereit、Sathya Gunasekaran、Daniel Ehrenberg
    • TC39 会议记录: July 2020
    • 发布时间:2021
  • Logical Assignment Operators
    • 作者:Justin Ridgewell
    • 维护者:Justin Ridgewell、Hemanth HM
    • TC39 会议记录: July 2020
    • 发布时间:2021
  • Numeric separators
    • 作者:Sam Goto、Rick Waldron
    • 维护者:Sam Goto、Rick Waldron、Leo Balter
    • TC39 会议记录: July 2020
    • 发布时间:2021

ES2020

  • String.prototype.matchAll
    • 作者:Jordan Harband
    • 维护者:Jordan Harband
    • TC39 会议记录: March 2019
    • 发布时间:2020
  • import()
    • 作者:Domenic Denicola
    • 维护者:Domenic Denicola
    • TC39 会议记录:June 2019
    • 发布时间:2020
  • BigInt
    • 作者:Daniel Ehrenberg
    • 维护者:Daniel Ehrenberg
    • TC39 会议记录: June 2019
    • 发布时间:2020
  • Promise.allSettled
    • 作者:Jason Williams、Robert Pamely、Mathias Bynens
    • 维护者:Mathias Bynens
    • TC39 会议记录: July 2019
    • 发布时间:2020
  • globalThis
    • 作者:Jordan Harband
    • 维护者:Jordan Harband
    • TC39 会议记录: October 2019
    • 发布时间:2020
  • for-in mechanics
    • 作者:Kevin Gibbons
    • 维护者:Kevin Gibbons
    • TC39 会议记录: December 2019
    • 发布时间:2020
  • Optional Chaining
    • 作者:Gabriel Isenberg、Claude Pache、Dustin Savery
    • 维护者:Gabriel Isenberg、Dustin Savery、Justin Ridgewell、Daniel Rosenwasser
    • TC39 会议记录: December 2019
    • 发布时间:2020
  • Nullish coalescing Operator
    • 作者:Gabriel Isenberg
    • 维护者:Gabriel Isenberg、Justin Ridgewell、Daniel Rosenwasser
    • TC39 会议记录:December 2019
    • 发布时间:2020
  • import.meta
    • 作者:Domenic Denicola
    • 维护者:Gus Caplan
    • TC39 会议记录: March 2020
    • 发布时间:2020

ES2019

ES2018

ES2017

ES2016

ES2015(ES6 元年特辑)

一路回溯到这里,终于轮到传说的起点。ES2015 和后面所有版本都不一样:它是最后一个"一揽子"发布的大版本,比 TC39 的分阶段流程还要早,finished-proposals 列表正是从 ES2016 才开始记录的,它的二十多个特性没有对应的提案条目可考,市面上的"历届特性"盘点也因此大多从 2016 年讲起。本文把这块拼图补上。

一句话背景:雄心过大的 ES4 在 2008 年宣告流产,委员会转向代号 Harmony 的务实路线,攒了六七年,于 2015 年 6 月 17 日一次性放出第 6 版。"每年一版"的节奏正是从这里开始的:憋了六年憋出个巨无霸,发布流程也被撑到极限,TC39 痛定思痛改成小步快跑,才有了上面那张图里的 11 根柱子。

类别特性
语法let / const、箭头函数、Class、模板字符串、解构赋值、默认参数、rest/spread、增强对象字面量
模块import / export(ES Modules)
异步Promise、Generator(function* / yield
集合与迭代Map / Set / WeakMap / WeakSet、迭代器协议、for...of
元编程SymbolProxy / Reflect
标准库Object.assignArray.from / Array.of / findString.prototype.includes、二进制/八进制字面量等一大批
其他尾调用优化(写进了规范,但至今只有 Safari 的 JavaScriptCore 真正实装)

这一版的分量有多重?后面 11 年加起来 78 个条目,而 ES2015 一个版本就重塑了语言的半张脸。所以招聘 JD 里的"精通 ES6",指的从来不是某一年,而是从这里开始的整个现代 JavaScript。

ES2027 预期新特性(前瞻)

ES2026 候选规范在 2026 年 3 月会议定稿,而 2026 年上半年 TC39 火力全开,4 个提案在截止线之后达到 Stage 4,按惯例它们将随 ES2027 发布。而且这批的分量,比 ES2026 正主还重:

  1. Temporal —— 九年长跑,终于冲线 🏁
  • Stage 4 时间: 2026 年 3 月 11 日(两大浏览器对约 5000 个 test262 一致性测试通过率均超 99.5% 后放行)
  • 说明: 全新的日期时间 API,Date 的"官方继任者":不可变对象、显式时区与日历、纳秒精度,Temporal.PlainDate / ZonedDateTime / Duration 等一整套类型
  • 实装进度: Firefox 139(2025 年 5 月)全球首发默认开启;Chrome 144(2026 年 1 月)跟进,V8 的实现复用了 Rust 库 temporal_rs;Safari 截至 2026 年中仍在 Technology Preview 打磨;Node.js 26 / Deno 2.7 已支持
  • 提案 2017 年启动,从"moment.js 之痛"走到标准,等它进 ES2027 正文的这一年里你已经可以在两大浏览器里直接用了
const meeting = Temporal.ZonedDateTime.from(
  '2026-07-12T10:00[Asia/Shanghai]'
);
meeting.add({ hours: 3 }).toString(); // 不可变,时区安全
Temporal.Now.plainDateISO().toString(); // '2026-07-12'
  1. Explicit Resource Management(using 声明)
  • Stage 4 时间: 2026 年 5 月 19 日(注意:2025 年它一直停在 Stage 3,不少文章提前把它算进 ES2025/ES2026,都是错的)
  • 说明: using / await using 声明 + Symbol.dispose / Symbol.asyncDispose + DisposableStack / AsyncDisposableStack,作用域结束自动释放资源(文件句柄、锁、流),JavaScript 版的 RAII / Python with
  • 实装进度: Chrome 134 / Firefox 141 / Node 24 / Deno 2.2 已支持,Safari 尚未;TypeScript 5.2 起可转译
async function copy(src, dst) {
  await using input = await fs.open(src);
  await using output = await fs.open(dst, 'w');
  // 离开作用域时二者自动调用 [Symbol.asyncDispose](),异常也不例外
}
  1. Joint Iteration(Iterator.zip / Iterator.zipKeyed)
  • Stage 4 时间: 2026 年 5 月 19 日
  • 说明: 多个迭代器并行走:Iterator.zip([a, b]) 产出元组,zipKeyed({ x: a, y: b }) 产出命名对象,支持长短不齐时的 shortest / longest / strict 模式
  • 实装进度: 目前仅 Firefox 148 稳定发布,其余引擎还在路上,是四个里离日常可用最远的一个
  1. Atomics.pause
  • Stage 4 时间: 2026 年 5 月 19 日(同场通过一项规范性变更:删除了原设计中的迭代次数参数,最终 API 是无参的 Atomics.pause(),网上旧文档里的 pause(N) 写法已作废)
  • 说明: 自旋锁场景下向 CPU 发出"微等待"提示(对应 x86 PAUSE 指令),降低多线程(SharedArrayBuffer + Worker)忙等的功耗与总线争用
  • 实装进度: Chrome 133 / Firefox 137 / Safari 18.4 / Node 24 已支持

以上四位,2027 年见。

TC39 提案动态速览(2025 下半年 → 2026 上半年)

除了定稿的特性,这一年 TC39 的大新闻还真不少,我们挨个看看:

📉 Decorators 罕见降级:2026 年 5 月 19 日,Decorators 从 Stage 3 被降回 Stage 2.7(Decorator Metadata 同日随行)。2022 年 3 月升 Stage 3 后苦等四年,没有任何浏览器原生实装,引擎方最终以"测试不完整、规范问题、实现复杂度"为由推动降级,会上甚至讨论了未来再降到 Stage 2 的可能性。TS / Babel 转译生态照常可用,但"原生装饰器"又遥遥无期了,这也是 Stage 2.7 设立以来最有名的一次"回炉"。

🪦 Records & Tuples 正式退场#{} / #[] 不可变原语值路线在 2025 年 4 月正式撤回,官方标注"由 Composites 接棒"(Stage 1)。新路线放弃新原语类型,改用普通对象语义的复合键,让 Map/Set 支持按值查找。

🔥 迭代器全家桶时代:继 ES2025 Iterator Helpers、ES2026 Iterator.concat、ES2027 Iterator.zip 之后,Iterator Chunkingchunks(n) / windows(n),Stage 3)、Iterator Includes(Stage 3,从 Stage 1 到 3 只用了约三个月,2026 年蹿升最快的提案)、Iterator Join(Stage 3)排队跟进,2026 年 5 月会议还专门讨论了迭代器提案路线图。

📦 模块和谐(Module Harmony)家族推进import defer(Stage 3,TypeScript 5.9 已支持语法,V8 已在 flag 后实现)、Import Text / Import Bytes(导入文本/二进制资源,分别 Stage 3 / 2.7)、import.sync(Stage 2),ES 模块正在补齐"非 JS 资源导入"与"细粒度加载时机控制"两块拼图。

其他看点:Immutable ArrayBuffer 拿到"有条件 Stage 3"(等 test262 落位);Error Stack Accessor 升 Stage 3(error.stack 终于要标准化了);沉寂四年半的 RegExp Buffer Boundaries(\A \z)复活并一周两连跳升 Stage 3;ShadowRealm 仍卡在宿主集成;AsyncContext 停在 Stage 2,浏览器对性能开销的顾虑未解。

结语

授人以鱼,不如授人以渔,希望通过本文追根溯源,带领同学们走进 ECMAScript 的世界,ES 神秘代码不再神秘,ES 新特性不再彷徨。

参考资料