ES2023 数组新方法 - 更优雅的不可变操作✒️ 墨染 | JavaScript 日更 | 2026-04-01 | #JavaScript #ES2023 #数组方法
ES2023 给数组带来了四个新方法:toSorted()、toReversed()、toSpliced() 和 with()。它们最大的特点:不改变原数组,返回新数组。 为什么需要这些方法?传统数组方法有个"坑":很多方法会原地修改数组。这在函数式编程、React 开发中会带来麻烦:
const arr = [3, 1, 2];
arr.sort(); // 原数组被修改!
console.log(arr); // [1, 2, 3]
// React 中这样写会出问题
const [list, setList] = useState([3, 1, 2]);
list.sort(); // ❌ 错误:直接修改了 state
setList(list); // React 检测不到变化 |
以前要避免修改原数组,需要手动拷贝:
// 老写法
const sorted = [...arr].sort();
const reversed = [...arr].reverse();
const spliced = [...arr]; spliced.splice(1, 1); |
ES2023 让这一切更直观。 toSorted() - 排序但不修改原数组
const arr = [3, 1, 2];
const sorted = arr.toSorted();
console.log(arr); // [3, 1, 2] 原数组不变
console.log(sorted); // [1, 2, 3] 新数组
// 支持比较函数
const desc = arr.toSorted((a, b) => b - a);
console.log(desc); // [3, 2, 1]
// 对象数组排序
const users = [
{ name: '张三', age: 25 },
{ name: '李四', age: 30 },
{ name: '王五', age: 20 }
];
const byAge = users.toSorted((a, b) => a.age - b.age); |
toReversed() - 反转但不修改原数组
const arr = [1, 2, 3];
const reversed = arr.toReversed();
console.log(arr); // [1, 2, 3]
console.log(reversed); // [3, 2, 1] |
with() - 替换指定索引的元素with(index, value) 返回一个新数组,指定位置的元素被替换:
const arr = ['a', 'b', 'c'];
const newArr = arr.with(1, 'B');
console.log(arr); // ['a', 'b', 'c'] 原数组不变
console.log(newArr); // ['a', 'B', 'c']
// 支持负索引(从末尾计数)
const lastReplaced = arr.with(-1, 'C');
console.log(lastReplaced); // ['a', 'b', 'C']
// 链式调用
const result = arr
.with(0, 'A')
.with(1, 'B')
.with(2, 'C');
console.log(result); // ['A', 'B', 'C'] |
toSpliced() - 删除/插入但不修改原数组toSpliced(start, deleteCount, ...items) 是 splice() 的不可变版本:
const arr = [1, 2, 3, 4, 5];
// 删除元素
const removed = arr.toSpliced(1, 2);
console.log(removed); // [1, 4, 5] 删除了索引1-2
// 插入元素(deleteCount 为 0)
const inserted = arr.toSpliced(2, 0, 'a', 'b');
console.log(inserted); // [1, 2, 'a', 'b', 3, 4, 5]
// 替换元素(删除 + 插入)
const replaced = arr.toSpliced(1, 2, 'x', 'y');
console.log(replaced); // [1, 'x', 'y', 4, 5]
console.log(arr); // [1, 2, 3, 4, 5] 原数组始终不变 |
React 中的实际应用这些方法在 React 中特别有用,因为 React 依赖不可变性来检测状态变化:
// ❌ 老写法 - 容易出错
const handleSort = () => {
const newList = [...list];
newList.sort((a, b) => a.name.localeCompare(b.name));
setList(newList);
};
// ✅ 新写法 - 简洁明了
const handleSort = () => {
setList(list.toSorted((a, b) => a.name.localeCompare(b.name)));
};
// ✅ 更新列表中某一项
const updateItem = (index, newValue) => {
setList(list.with(index, newValue));
};
// ✅ 删除某一项
const removeItem = (index) => {
setList(list.toSpliced(index, 1));
}; |
方法对比表
| 老方法 |
新方法 |
区别 |
sort() |
toSorted() |
原地修改 vs 返回新数组 |
reverse() |
toReversed() |
原地修改 vs 返回新数组 |
splice() |
toSpliced() |
原地修改 vs 返回新数组 |
arr[i] = v |
with(i, v) |
原地修改 vs 返回新数组 |
⚠️ 注意事项
- 新方法返回的是浅拷贝,数组元素仍是引用
- 旧方法(如
sort())仍可用,在需要原地修改时更高效
- Node.js 20+、Chrome 110+、Firefox 115+ 支持
- IE 和旧浏览器需要 polyfill
总结ES2023 的数组新方法让 JavaScript 的不可变操作更加优雅:
toSorted() - 排序后返回新数组
toReversed() - 反转后返回新数组
with() - 替换指定索引返回新数组
toSpliced() - 删除/插入后返回新数组
如果你用 React、Vue 或其他强调不可变性的框架,这些方法会让你的代码更简洁、更安全。
✒️ 墨染 | JavaScript 日更系列 | Day 36
上一篇:JavaScript 闭包原理 | 下一篇:ES6 箭头函数 vs 普通函数 |
评论
发表评论