讲解
ECMAScript 每年更新一次,近几批(ES2022–ES2024)加入了不少即学即用的特性,现代浏览器和 Node 18+ 大多已支持。ES2022:类的公有/私有字段与静态块(classes 一章已讲)、数组和字符串的 at() 方法(arr.at(-1) 取倒数第一个,替代 arr[arr.length - 1])、Object.hasOwn(安全的自有属性判断)、顶层 await(模块里直接 await,不用包 async 函数)。
ES2023 的主菜是「不可变数组方法」:toSorted、toReversed、toSpliced、with 分别对应 sort、reverse、splice、按索引替换,但返回新数组、不动原数组——这正好补上了数组方法一章强调的「原地修改」隐患,配合 findLast/findLastIndex(从尾部查找)一起使用。ES2024 带来 Object.groupBy / Map.groupBy(按条件给数组分组,以前要手写 reduce)、Promise.withResolvers(把 resolve/reject 拿到 Promise 外使用,包装回调式 API 更顺手)。
学习新特性的正确姿势:先看运行环境支持(caniuse.com 或 node 版本),需要兼容旧环境时用构建工具(Babel)降级或 polyfill;不要盲目追新——at()、toSorted() 这类方法确实让代码更短更清晰,值得立刻上手;而语法层面的新奇特性如果没有解决你的实际问题,晚一点用也无妨。
示例
// at():优雅的倒数取值
const list = ['甲', '乙', '丙'];
console.log('倒数第一:', list.at(-1), '正数第二:', list.at(1));
// Object.hasOwn:安全的自有属性判断
const obj = { a: 1 };
console.log(Object.hasOwn(obj, 'a'), Object.hasOwn(obj, 'toString'));
// 不可变数组方法(ES2023):返回新数组
const nums = [3, 1, 2];
const sorted = nums.toSorted((a, b) => a - b);
console.log('排序副本:', sorted, '原数组不变:', nums);
console.log('反转副本:', nums.toReversed());
console.log('替换下标 1:', nums.with(1, 99), '原数组仍是:', nums);
console.log('删除下标 0:', nums.toSpliced(0, 1));
// findLast:从尾部查找
const scores = [45, 90, 55, 80];
console.log('最后一个及格分:', scores.findLast((s) => s >= 60));
// Object.groupBy(ES2024):按条件分组
const products = [
{ name: '苹果', type: '水果' },
{ name: '白菜', type: '蔬菜' },
{ name: '香蕉', type: '水果' },
];
const grouped = Object.groupBy(products, (p) => p.type);
console.log('水果:', grouped['水果'].map((p) => p.name));
console.log('蔬菜:', grouped['蔬菜'].map((p) => p.name));
// Promise.withResolvers(ES2024):在 Promise 外控制落定
const { promise, resolve } = Promise.withResolvers();
resolve('由外部触发');
promise.then((v) => console.log('收到:', v));
常见坑
- 没确认运行环境就用:toSorted 需要 Chrome 110+/Node 20+,Object.groupBy 需要 Chrome 117+/Node 21+;面向旧浏览器的产品要经构建工具降级。
- 混淆可变与不可变成对方法:toSorted 不改原数组、sort 改;混用时一边期待原数组变了一边没变,bug 隐蔽。决定风格后保持一致。
- at() 与下标行为差异:at(-1) 对越界负数返回 undefined,不会绕圈;而 arr[arr.length] 也是 undefined——迁移旧代码时语义一致,但 at 不接受小数下标取整等隐式行为差异要留意。
- groupBy 的键转成字符串:Object.groupBy 的分组键是字符串(数字键也变字符串),需要保留原始键类型用 Map.groupBy。
小结
at、Object.hasOwn、toSorted 系、findLast、Object.groupBy、Promise.withResolvers 是近年最值得上手的新特性;用前确认环境支持,风格保持一致。至此,50 章教程到此结束——去写代码吧,实践是最好的老师。