ES2026 正式发布!这 7 个 JavaScript 新特性正在改变你的代码(附完整示例)
ES2026 正式发布!这 7 个 JavaScript 新特性正在改变你的代码(附完整示例)

2026 年 7 月,Ecma 国际大会正式批准了 ECMAScript 2026(即 ES2026,规范第 17 版)。作为一年一度的 JavaScript 语言"年度快照",ES2026 没有大刀阔斧的语法革命,却一口气补齐了开发者在数字精度、二进制数据、错误处理、集合操作、异步流等高频场景下的痛点。毫不夸张地说,这份规范里的大部分特性,都是"你早就该有、却一直手写轮子"的 API。
本文带你逐个过一遍 ES2026 的 7 个新特性,每个都附可直接运行的真实代码,最后再聊一聊那个"虽未进 ES2026、但今天就能用"的明星提案——Temporal API。
一、Math.sumPrecise:浮点求和不再"翻车"
先看一个经典面试题:`0.1 + 0.2` 等于多少?答案是 `0.30000000000000004`。因为浮点数在二进制下无法精确表示十进制小数,累加时误差还会不断累积:
// 老写法:误差累积 const prices = [19.99, 5.5, 3.33, 0.1]; const total = prices.reduce((sum, n) => sum + n, 0); console.log(total); // 28.920000000000005 😱 // ES2026:精确求和 const total2 = Math.sumPrecise(prices); console.log(total2); // 28.92 ✅`Math.sumPrecise()` 内部采用 Neumaier 补偿求和算法,把每次相加产生的舍入误差单独记录下来并回补,从而把误差控制在可接受范围内。它接受一个可迭代对象,返回精确求和结果。对财务计算、统计聚合、科学计算来说,这是根治 `+` 运算符误差累积的正解。
二、Uint8Array 原生 Base64 / Hex:告别 btoa 与手写转换
过去做二进制编码转换,前端用 `btoa`/`atob`(还常常被 Unicode 中文坑),后端用 `Buffer.toString('base64')`,Node 与浏览器各写一套。ES2026 给 `Uint8Array` 增加了四个静态/实例方法:
// 字符串 → Uint8Array → Base64 const bytes = Uint8Array.fromBase64("aGVsbG8gd29ybGQ="); console.log(new TextDecoder().decode(bytes)); // "hello world" // Uint8Array → Base64 console.log(bytes.toBase64()); // "aGVsbG8gd29ybGQ=" // 十六进制同样原生支持 const hex = Uint8Array.fromHex("48656c6c6f"); console.log(new TextDecoder().decode(hex)); // "Hello" console.log(hex.toHex()); // "48656c6c6f"从此加密摘要、图片上传、文件分片等场景无需再引入第三方库,也无需在 Node 与浏览器之间写兼容层——一套 API 通吃。
三、Error.isError:跨 Realm 的错误检测
`instanceof Error` 有个著名的坑:跨 iframe、跨 worker、跨 Node 模块上下文(realm)时,不同 realm 的 `Error` 构造函数不是同一个,`instanceof` 会返回 `false`,导致 try/catch 里的兜底逻辑失灵。`Array.isArray` 解决过同样的问题,ES2026 的 `Error.isError` 如法炮制:
function safeParse(json) { try { return JSON.parse(json); } catch (err) { // 老写法:err instanceof Error 在跨 realm 时可能为 false // 新写法:可靠检测任意 realm 的错误对象 if (Error.isError(err)) { console.error("解析失败:", err.message); } else { console.error("抛出了非 Error 对象:", err); } return null; } }它还顺带解决了"抛字符串/抛数字"这类历史遗留问题——`Error.isError("oops")` 返回 `false`,而 `Error.isError(new TypeError("oops"))` 返回 `true`。
四、Map.getOrInsert:一行代码搞定 Upsert
"从 Map 里取值,没有就放默认值"——这是业务代码里出现频率极高的模式。过去你必须这样写:
// 老写法:三行样板代码 let count = visits.get(userId); if (count === undefined) { visits.set(userId, 1); count = 1; } // ES2026:一行搞定 const count2 = visits.getOrInsert(userId, 1);`getOrInsert(key, value)`:key 存在则返回原值;不存在则插入 value 并返回它。还有一个配套方法 `getOrInsertComputed(key, () => compute())`,延迟计算默认值,适合默认值构造开销大的场景(比如要 new 一个对象或请求配置)。配合缓存、计数、去重、分组统计等场景,代码可读性直接上一个台阶。
五、Array.fromAsync:异步迭代器一键转数组
ES2015 带来了 `Array.from()`,但它只能处理同步可迭代对象。面对异步生成器、异步流式接口,过去你得手写 `for await` 循环:
// 老写法 const results = []; for await (const item of fetchPages()) { results.push(item); } // ES2026:一行 const results2 = await Array.fromAsync(fetchPages());`Array.fromAsync` 同样支持映射函数,例如 `await Array.fromAsync(gen(), (x) => x * 2)`。分页拉取、流式读取、批量并发处理这些"异步 + 收集"的场景,从此有了统一的原生表达。
六、Iterator.concat:迭代器也能"拼接"
ES2025 引入了迭代器助手(Iterator Helpers),ES2026 继续补齐:新增静态方法 `Iterator.concat()`,把多个可迭代对象串联成一个惰性迭代器,逐个遍历,不产生中间数组:
const list = Iterator.concat( [1, 2, 3], // 数组 new Set([4, 5]), // Set (function* () { yield 6; })(), // 生成器 ); console.log([...list]); // [1, 2, 3, 4, 5, 6]因为是惰性求值,即使拼接的数据源是无限生成器,只要你在中途 `break`,它也不会多消费一个元素。合并日志、拼接分页数据、组合配置项,都非常顺手。
七、JSON.parse 的 source 文本:大整数不再丢精度
`JSON.parse('{"id": 9007199254740993}')` 得到的数字会变成 `9007199254740992`——超过 `Number.MAX_SAFE_INTEGER` 的整数精度丢失,这是后端传大 ID 时前端最常见的隐性 bug。ES2026 给 reviver 回调新增了第三个参数 `context`,你可以拿到键对应的原始文本:
const json = '{"id": 9007199254740993, "name": "Hermes"}'; const obj = JSON.parse(json, (key, value, context) => { if (key === "id") { // context.source 是未经过数字解析的原始字符串 return BigInt(context.source); // 9007199254740993n,精度无损 } return value; }); console.log(obj.id); // 9007199254740993n ✅这样就能精确处理大整数、高精度小数等场景,无需再引入 `json-bigint` 之类的库,也不怕 `Number` 的精度陷阱。
专题:Temporal API —— 等了 9 年的 Date 替代者
严格来说,Temporal没有进入 ES2026 快照(TC39 于 2026 年 3 月将其推进到 Stage 4,预计收录于 ES2027)。但它的实现已经遍布主流浏览器(Chrome 131+、Firefox 134+)与 Node.js 22+,今天就能用于生产,因此被公认为 2026 年 JavaScript 最值得关注的大事。
`Date` 对象的"罪状"众所周知:可变、时区混乱、只支持毫秒、日期运算全靠手写。Temporal 提供了不可变的、时区感知的现代 API:
// 当前日期(ISO 日历) const today = Temporal.Now.plainDateISO(); console.log(today.toString()); // 2026-08-12 // 日期运算:加两个月,自动处理闰年与月末 const deadline = Temporal.PlainDate.from("2026-08-12").add({ months: 2 }); console.log(deadline.toString()); // 2026-10-12 ✅ // 时区感知的精确时刻 const now = Temporal.Now.zonedDateTimeISO("Asia/Shanghai"); console.log(now.toLocaleString("zh-CN")); // 2026/8/12 14:00:00 GMT+08:00 // 计算两个日期相差的天数 const days = Temporal.PlainDate.from("2026-08-12") .until(Temporal.PlainDate.from("2026-10-01")).days; console.log(days); // 50Temporal 覆盖了 `PlainDate`、`PlainTime`、`ZonedDateTime`、`Duration` 等 10 个类型,配合 `Intl.DurationFormat` 还能直接输出"2 小时 15 分钟"这类本地化文案。对日期敏感的预订系统、排期系统、国际化业务,建议尽早用 `@js-temporal/polyfill` 平滑迁移。
兼容性与升级建议
一句话总结各特性的可用情况:
• **已广泛可用**:`Array.fromAsync`、`Error.isError`、`Math.sumPrecise`、`Map.getOrInsert`(Chrome 137+ / Firefox / Safari / Node 22+ 逐步落地)
• **逐步铺开**:`Uint8Array` Base64/Hex、`Iterator.concat`、`JSON.parse` source 文本
• **即将到来**:`Temporal`(Stage 4,浏览器已支持,正式进规范预计 ES2027)、`using` 显式资源管理、`import defer` 延迟导入
给团队三个可落地的建议:
1.低风险先上:`Math.sumPrecise`、`Map.getOrInsert`、`Error.isError` 属于纯增量 API,不破坏任何现有代码,直接在 lint 规则里推荐即可。
2.重点项目试用:新项目把 `Array.fromAsync`、`Uint8Array` 编解码写进团队代码规范,减少第三方依赖。
3.Temporal 提前布局:虽然它预计 2027 年才进规范,但 API 已冻结、polyfill 生产可用,日期处理密集的业务现在就可以开始迁移,越晚成本越高。
总结
ES2026 是典型的"补课型"版本——没有炫技语法,但每一个特性都精准命中开发者日常的痛点:精度、编码、检测、集合、异步、解析。它传递的信号很明确:JavaScript 正在从"够用"走向"好用"。建议收藏本文,对照检查你的代码里还有哪些"手写轮子"可以替换成原生 API。如果你已经在生产环境用上了这些特性,欢迎在评论区分享踩坑经验!
---
本文基于 ECMAScript 2026 正式规范(2026 年 7 月批准)与 TC39 提案进度整理,示例代码可在最新版 Chrome / Node.js 中直接运行。