ES2022-2025实用特性盘点:让JavaScript代码更短更安全

更新日期: 2026-04-02 阅读: 19 标签: 特性

日常写JS时,往往用顺手的那几招就够用了。但ECMAScript每年都会加一批小改进——不搞大新闻,却能让代码更短、更安全、更好读。这篇文章整理了一批近几年落地的实用特性,并配上代码示例,方便你在真实项目里直接用起来。


一、ES2022:少写废话,多写意图

1. 顶层await

解决啥问题:以前在模块顶层想「先拉配置再往下跑」,只能包一层async函数再调用,多一层壳。

以前常见写法:

async function bootstrap() {
  const settings = await loadSettings();
  runApp(settings);
}
bootstrap();

现在可以这样:

const settings = await loadSettings();
runApp(settings);

模块顶层直接await,启动逻辑更直观,少一点仪式感。

2. 私有字段(#)

解决啥问题:JS一直没真正的类私有字段,大家用_private之类的约定,本质上还是「君子协定」。

现在可以这样:

class TaskQueue {
  #pending = [];

  enqueue(task) {
    this.#pending.push(task);
  }

  get size() {
    return this.#pending.length;
  }
}

在类外访问instance.#pending会直接报错,封装更实在。

3. Error的cause

解决啥问题:一层层往上抛错时,原始错误容易丢,排查时要猜「到底是哪一环出的问题」。

现在可以这样:

try {
  await fetchFromAPI();
} catch (e) {
  throw new Error('请求失败', { cause: e });
}

日志和DevTools里能看到完整错误链,定位更快。

4. Object.hasOwn()

解决啥问题:判断「是不是自有属性」以前要写Object.prototype.hasOwnProperty.call(obj, 'key'),又长又容易在边缘情况踩坑。

以前:

if (Object.prototype.hasOwnProperty.call(config, 'env')) {
  useEnv(config.env);
}

现在:

if (Object.hasOwn(config, 'env')) {
  useEnv(config.env);
}

语义清晰,写法也干净。

5. 数组的.at()(负索引)

解决啥问题:取「最后一个元素」总要写arr[arr.length - 1],取倒数第二个更啰嗦。

以前:

const last = items[items.length - 1];
const secondLast = items[items.length - 2];

现在:

const last = items.at(-1);
const secondLast = items.at(-2);

负索引从末尾算起,可读性更好。


二、ES2023:少改原数据,多返回新数据

这一批的主线是:尽量不原地修改,避免共享引用带来的隐蔽bug。

6. toSorted() / toReversed() / toSpliced()

解决啥问题:sort()、reverse()、splice()都会改原数组,一不留神就影响到别处。很多人只好先[...arr].sort(),语义不直接。

以前常见写法:

const byDate = [...list].sort((a, b) => a.date - b.date);
const reversed = [...list].reverse();

现在:

const byDate = list.toSorted((a, b) => a.date - b.date);
const reversed = list.toReversed();
const withoutSecond = list.toSpliced(1, 1); // 去掉下标1的一个元素,返回新数组

原数组不变,返回新数组,更适合状态管理和函数式写法。

7. findLast() / findLastIndex()

解决啥问题:只有find时,要找「最后一个满足条件的」要么自己倒着循环,要么[...arr].reverse().find(fn),既啰嗦又可能误用reverse。

以前:

const lastEven = [...nums].reverse().find((n) => n % 2 === 0);

现在:

const lastEven = nums.findLast((n) => n % 2 === 0);
const lastEvenIndex = nums.findLastIndex((n) => n % 2 === 0);

意图一眼能看懂。


三、ES2024:数据分组与异步控制

8. Object.groupBy()

解决啥问题:按某个键把数组分组,以前要么手写reduce,要么自己封一个groupBy工具函数。

以前:

const byStatus = list.reduce((acc, item) => {
  const k = item.status;
  if (!acc[k]) acc[k] = [];
  acc[k].push(item);
  return acc;
}, {});

现在:

const byStatus = Object.groupBy(list, (item) => item.status);

注意:键会变成字符串。若要用对象/其他类型当键,用Map.groupBy()。

9. Promise.withResolvers()

解决啥问题:需要「先拿到resolve/reject,稍后再调用」时,以前要在外层声明变量再塞进new Promise,写法别扭。

以前:

let resolve;
const done = new Promise((r) => { resolve = r; });
// 某事件触发后:resolve(value);

现在:

const { promise, resolve, reject } = Promise.withResolvers();
// 某事件触发后:resolve(value);

事件、队列、超时等场景里会清爽很多。

10. 可调整大小的ArrayBuffer

解决啥问题:以前ArrayBuffer长度固定,流式或动态长度时要自己管理多段buffer。

现在可以指定最大长度:

const buffer = new ArrayBuffer(256, { maxByteLength: 4096 });
// 后续可通过.resize()在256~4096之间调整

适合流式、Worker、二进制协议等场景。


四、ES2025:迭代器、集合与安全正则

11. 迭代器上的map / filter / take

解决啥问题:数组链式map → filter → slice会每一步都生成新数组,数据量大时浪费内存。迭代器可以「按需计算」,不先占满内存。

以前(每一步都是新数组):

const result = data.map((x) => x.value).filter((v) => v > 0).slice(0, 10);

现在(懒求值,用迭代器):

const result = data.values()
  .map((x) => x.value)
  .filter((v) => v > 0)
  .take(10)
  .toArray();

适合大列表、流式数据或无限序列。注意:这里的map/filter/take是迭代器上的方法,和Array.prototype上的不同,需要先拿迭代器(如arr.values())。

12. Set的intersection / union / difference

解决啥问题:求交集、并集、差集以前要自己用filter、has拼,或者转成数组再算。

以前:

const both = new Set([...a].filter((x) => b.has(x)));
const all = new Set([...a, ...b]);

现在:

const both = a.intersection(b);
const all = a.union(b);
const onlyInA = a.difference(b);

集合运算更贴近数学表达,可读性更好。

13. RegExp.escape()

解决啥问题:用用户输入拼正则时,输入里若有( ) [ ] * + ?等会变成正则语法,既容易报错也有安全风险。以前要自己写一长串replace转义。

现在:

const safe = RegExp.escape(userInput);
const re = new RegExp(safe, 'i');

动态正则更安全,也省得自己维护转义规则。

14. Promise.try()

解决啥问题:有的函数可能同步抛错、也可能返回Promise,想统一用await包一层时,要自己区分sync/async。Promise.try把「可能抛错的同步/异步逻辑」统一成Promise。

示例:

const result = await Promise.try(() => maybeSyncOrAsync());

这样无论函数是同步抛错还是返回Promise,都能用同一套错误处理。

15. Float16Array

解决啥问题:以前只有Float32/Float64,在WebGPU、部分ML或紧凑二进制格式里需要16位浮点。

现在:

const data = new Float16Array(1024);

更省内存,也方便和GPU/跨语言二进制格式对接。


五、整体在往哪走

拉远一点看,这几年JS的更新有一个共同方向:

  • 少改原数据:toSorted、toReversed、toSpliced、findLast等,都在鼓励「返回新的」而不是「改原来的」

  • 意图更明确:hasOwn、at(-1)、groupBy、Set的intersection/union/difference,名字即语义

  • 异步更稳:顶层await、Error.cause、Promise.withResolvers、Promise.try,让异步和错误链更清晰

  • 更安全、更省资源:私有字段、RegExp.escape、迭代器懒求值、Float16Array,分别在封装、安全、性能和内存上补了一块

不必追求「全背下来」——用到时查一下MDN或Node文档即可。更值得做的是:知道有这些能力存在,下次写reduce分组、取最后一个元素、或「不改变原数组的排序」时,能想到用新API,代码会更好维护。

如果你有固定用的Node版本,可以先在Node兼容表或caniuse上看下目标环境是否支持;部分ES2025特性需要较新的运行时(如Node 22+)。按需选用,就能把这些「悄悄好用」的特性真正用起来。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13556

相关推荐

Html5、Css3、ES6的新特性

Html5的新特性语义化标签:有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重。表单新特性,多媒体视频(video)和音频(audio)

Js的用途和特性

JavaScript 最初的目的是为了“赋予网页生命”。这种编程语言我们称之为脚本。它们可以写在 HTML 中,在页面加载的时候会自动执行。脚本作为纯文本存在和执行。它们不需要特殊的准备或编译即可运行。

Angular 8的新特性介绍

在今天早些时候Angular团队发布了8.0.0稳定版。其实早在NgConf 2019大会上,演讲者就已经提及了从工具到差分加载的许多内容以及更多令人敬畏的功能。下面是我对8.0.0一些新功能的简单介绍,希望可以帮助大家快速了解新版本

Js即将到来的3个新特性

Optional Chaining(可选链式调用);Nullish coalescing(空值合并);Pipeline operator(管道运算符)通过三个函数对字符串进行处理;

CSS新特性contain,控制页面的重绘与重排

contain 属性允许我们指定特定的 DOM 元素和它的子元素,让它们能够独立于整个 DOM 树结构之外。目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。

ES2019 新特性汇总

最近 ECMAScript2019,最新提案完成:tc39 Finished Proposals,我这里也是按照官方介绍的顺序进行整理,如有疑问,可以查看官方介绍啦~另外之前也整理了 《ES6/ES7/ES8/ES9系列》,可以一起看哈。

ES9(2018)新特性:异步迭代、Promise.finally、Rest/Spread等

ES9是ECMA协会在2018年6月发行的一个版本,因为是ECMAScript的第九个版本,所以也称为ES9。本篇文章介绍ES2018(ES9)的新特性,来看看怎么使用它们。

解密HTTP/2与HTTP/3 的新特性

HTTP/2 相比于 HTTP/1.1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何优雅降级应该是国内还不普遍使用的原因之一。

十个超级实用的 JS 特性

你可能刚上手 JavaScript,或者只是曾经偶尔用过。不管怎样,JavaScript 改变了很多,有些特性非常值得一用。 这篇文章介绍了一些特性,在我看来,一个严肃的 JavaScript 开发者每天都多多少少会用到这些特性

ES6新特性--var、let、const

var不存在块级作用域,具有变量提升机制。 let和const存在块级作用域,不存在变量提升。在同一作用域内只能声明一次。const在声明时需要赋值且无法修改,但如果常量是对象,则对象的属性可以修改。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!