👇 今日要闻
打破信息壁垒,走近全球前端。Hello 大家好,我是林语冰。
ECMAScript 是 JS 的官方标准,每年都会为 JS 引入一些新功能提案,并上线已经到达 Stage4 第四阶段的标准提案,入驻当年最新的《ECMAScript 语言规范》。
ES2026 正式上线了下列 7 项新功能:
JSON.parse()源文本访问提案Math.sumPrecise提案Error.isError()提案Uint8Array与 Base64 互转提案- 迭代器序列提案
Array.fromAsync()提案Map插入提案
本期我们一起来速览一下 ES2026 全新推出的七大功能,大家可以思考一下它们适用哪些场景,是否有助于解决现存 JS 开发中的某些"代码屎山"。
👉 Error.isError()
类似于 Array.isArray() API,ES2026 新增了 Error.isError(),这是一个精准判断 Error 及其派生子类实例的静态方法。
以前,使用 instanceof 操作符判断 Error 的相关实例可能误判,产生所谓"假阳性"或"假阴性"的结果:

可以看到,Error.isError() 方法底层的判断机制比 instanceof 操作符更严格。
此外,instanceof 操作符在涉及浏览器 window.iframes 或 Node.js 的 node:vm 模块等 cross-realm 跨领域判断时,也会导致运行时误判行为,而 Error.isError() 是一种更鲁棒的替代方案。
👉 Math.sumPrecise()
ES2026 新增了 Math.sumPrecise() 静态方法,它接受一个数字类型的可迭代对象,结果返回这些数字的总和。
以前,对一个数字数组求和的常用方案是 Array.prototype.reduce() 实例方法:

这里,数组元素叠加求和,首尾项正负相抵,理论上预期结果应该返回 0.1,但结果竟然为 0!!!
这是因为,不管是使用命令式的 for 循环还是函数式的 reduce() 方法,1e20 + 0.1 都无法使用 64 位浮点数精确表示,这里 JS 采用的数字标准会导致精度失真,中间结果只能四舍五入为 1e20;然后,1e20 和 -1e20 相加的和为 0。
ES2026 上线了 Math.sumPrecise() 静态方法来解决这种极端情况,它采用了一种和 Python math.fsum 相同的特殊求和算法,但同时会处理中间溢出确保精度:

可以看到,Math.sumPrecise() 方法能在确保精度的前提下对数字可迭代对象求和,0.1 + 0.2 !== 0.3 的经典套路也印证了其可信的精度。
👉 JSON 源文本访问
精度失真问题不仅经常发生在数学计算中,也常见于 JSON 序列化和反序列化等场景。
举个栗子,反序列化数字时,会出现下列"灵异现象":

可以看到,使用 JSON.parse() 进行反序列化后的数字结果已经失真了......
为此,ES2026 JSON 源文本访问提案扩展了原有的 JSON.parse() 和 JSON.stringify() API,同时新增了两个相关的 API:
JSON.isRawJSON()JSON.rawJSON()
以 JSON.parse() 为例,新版 JSON.parse() 的 reviver 回调函数新增了一个特殊的上下文形参:

可以看到,通过暴露 reviver 回调函数的第三个新参数,我们可以从 ctx 上下文中访问到 source 源文本,从而按需定义反序列化逻辑,更加灵活。
👉 Uint8Array 转化
前端工程的一种优化是把图片转化为 Base64 字符串,Base64 编码可以把任意二进制数据表示为 ASCII 编码。目前 JS 已经支持 Uint8Array 处理二进制数据,但没有提供将数据编码为 Base64 的方法。
为此,ES2026 在 Uint8Array 构造函数及其原型上新增了一组 API,用于将二进制数据编码为 Base64 或转化为十六进制字符串:
Uint8Array.fromBase64()Uint8Array.fromHex()Uint8Array.prototype.setFromBase64()Uint8Array.prototype.setFromHex()Uint8Array.prototype.toBase64()Uint8Array.prototype.toHex()
以 Base64 和 Uint8Array 二进制数据的转化为例,基本用法如下:

现在,如果你想实现 Base64 编码相关的转化逻辑或优化工具,自定义封装会更加方便,甚至无需依赖第三方模块。
👉 Map 静态方法
ES2026 在 Map 和 WeakMap 构造函数的原型上新增了四个实例方法:
Map.prototype.getOrInsert()Map.prototype.getOrInsertComputed()WeakMap.prototype.getOrInsert()WeakMap.prototype.getOrInsertComputed()
这四个方法的基本思想都大同小异,主要用于简化 Map + if 条件判断键是否存在的常见模式。
以 map.getOrInsert() 方法为例,它的基本原理如下:

可以看到,map.getOrInsert() 方法会先判断键目标键是否存在,如果存在,则返回该键对应的值;如果键不存在,则使用默认值进行初始化。
举个栗子,实际开发中,网站支持深浅主题时一般会缓存用户偏好设置:

这样,ES2026 以前需要频繁手写的 if / else 模板代码,都能使用一行代码来简化,map.getOrInsert() 本质上可以视为 Map 数据结构用于键判断和默认初始化结合的一个"方法糖"。
👉 Iterator 序列
类似 [].concat(),ES2026 为迭代器新增了 Iterator.concat() 静态方法,用于有序拼接多种可迭代对象。
以前,拼接多个迭代器需要借助生成器函数来实现:

ES2026 之后使用 Iterator.concat() 直接拼接即可:

👉 Array.fromAsync()
类似 Array.from(),ES2026 新增了异步编程版本的 Array.fromAsync() 静态方法,用于简化异步可迭代对象使用 for await...of 的迭代逻辑。
举个栗子,以前不管是生成 Promise 的同步生成器函数还是异步生成器函数,它们生成的可迭代对象都需要通过 for await...of 来消费:

可以看到,for await...of 可以顺利处理异步可迭代对象,但不像 Array.from() 那样优雅。
这正是 ES2026 Array.fromAsync() 的用武之地:

可以看到,Array.fromAsync() 方法可以完美镜像 for await..of 的逻辑。
⚠️ 注意️,异步编程时,需要区分串行的 Array.fromAsync() vs 并行的 Promise.all():
| 并行 await | 串行 await | |
|---|---|---|
| 惰性迭代 | ❌ | Array.fromAsync() |
| 急性迭代 | Promise.all(Array.from()) | ❌ |
👇 重点总结

今年最新的 ES2026 已经顺利通过 TC39 技术委员会的审核,且由 Ecma 国际组织正式批准,一共推出了七大新功能。
其中除了 Error.isError() 提案属于限用基线,暂未被苹果 Safari 浏览器支持,其他六大提案均已到达新晋基线,所有最新版本的主流浏览器均已支持,预计今年以内所有提案都会成为新晋可用基线。
随着 ES2026 顺利批准,JS 再次进化,Map 等判断模式的模板代码可以被新方法简化,Base64 编码缺失的坑被填上,数字精度丢失问题有了新的解决方案,开发体验更好,也更符合人体工学。
👍 以上就是本期《前端日报》的全部内容了,如果读完对你有所帮助,可以按赞打卡、在看推荐或转发分享。
🙏 已经关注我的粉丝们,我们下期再见啦,掰掰~~

👇 参考文献:
- 🔗 ES2026 语言规范 :262.ecma-international.org/17.0/index....
- 🔗 tc39 仓库 :github.com/tc39/propos...