- 清单
- Array.prototype.toSorted
- Array.prototype.toReversed
- Array.prototype.with
- Array.prototype.findLast
- Array.prototype.findLastIndex
- Array.prototype.toSpliced
- 正式的 shebang 支持
- Symbol 作为 WeakMap 的键
- 总结
本文将为大家梳理下 ES14 最新规范新增功能:对数组的新增功能,对 shebang 的支持,对弱引用集合的符号键的扩展。这个版本的都是一些细微的改进,我们一起看看有哪些变化。
清单
- Array.prototype.toSorted
- Array.prototype.toReversed
- Array.prototype.with
- Array.prototype.findLast
- Array.prototype.findLastIndex
- Array.prototype.toSpliced
- 正式的 shebang 支持
- Symbol 作为 WeakMap 的键
Array.prototype.toSorted
toSorted()
与 Array.prototype.sort()
具有相同的签名,但它创建一个新的数组,而不是对原数组进行操作。
let arr = [5, 4, 2, 3, 1]; arr === arr.sort(); // true - [1, 2, 3, 4, 5] arr === arr.toSorted(); // false - [1, 2, 3, 4, 5]
toSorted()
和 sort()
一样,接受一个可选参数作为比较函数。例如,我们可以使用 toSorted() 创建一个按降序排列的新数组
const numbers = [10, 5, 2, 7, 3, 9, 1, 6, 4]; const sortedNumbers = numbers.toSorted((a, b) => { return b - a; }); console.log(sortedNumbers); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
需要注意的是,toSorted()
也可以应用于对象数组。这种情况下,需要提供一个使用对象上的数据的比较函数,因为对象没有自然的排序方式。
// 比较对象 const objects = [ { name: "John", age: 30 }, { name: "Jane", age: 25 }, { name: "Bill", age: 40 }, { name: "Mary", age: 20 } ]; const sortedObjects = objects.toSorted((a, b) => { return a.name.localeCompare(b.name); }); console.log(sortedObjects); // [{"name":"Bill","age":40},{"name":"Jane","age":25},{"name":"John","age":30},{"name":"Mary","age":20}]
Array.prototype.toReversed
与 toReversed()
和 reverse()
一样,toReversed() 是 reverse() 的复制版本。
["a", "b", "c", "d", "e"].toReversed(); // ['e', 'd', 'c', 'b', 'a']
Array.prototype.with
新的 with()
方法允许您基于索引修改单个元素,并返回一个新的数组。因此,如果您知道索引和新值,这个方法非常方便。
const arr4 = ["I", "am", "the", "Walrus"]; // 用 "Ape Man" 替换字符串 "Walrus"。 const newArr4 = arr4.with(3, "Ape Man"); console.log(newArr4);
Array.prototype.findLast
findLast()
方法允许您从数组中获取匹配元素的最后一个实例。如果找不到匹配元素,则返回 undefined。下面代码中提供了一个简单的示例,我们从数组中获取最后一个偶数。
const arr = [54, 34, 55, 75, 98, 77]; const lastEvenIndex = arr.findLast((element) => { return element % 2 === 0; }); console.log(lastEvenIndex); // 98
findLast()
还支持传递一个 “thisArg” 来设置上下文。也就是说,第二个参数将告诉第一个参数函数 this 关键字将引用什么。从下面代码中看到这一点,我们使用一个自定义对象来找到可以被 5 整除的第一个元素。
const arr6 = [54, 34, 55, 75, 98, 77]; const myObject = { testCase: 5 }; const lastEvenIndex = arr5.findLast((element) => { return element % myObject.testCase === 0; }, myObject); console.log(lastEvenIndex); // 75
Array.prototype.findLastIndex
findLastIndex()
的工作方式与 findLast()
相同,只是它返回匹配元素的索引而不是元素本身。例如,下面例子展示如何找到最后一个可以被 6 整除的元素的索引。
const arr = [54, 34, 55, 75, 98, 77]; arr.findLastIndex(x => x % 6 === 0); // 0
Array.prototype.toSpliced
上面新增的所有方法也适用于 TypedArray,但 toSpliced()
这个新的数组方法只存在于 Array 中。toSpliced() 方法是 splice()
的复制版本,splice()是 js 中数组操作常用的方法;
假设我们有一个颜色数组,需要在中间插入一些新的颜色(粉红色和青色)。这会创建一个新数组,而不是修改原始数组。
const arr = ["red", "orange", "yellow", "green", "blue", "purple"]; const newArr = arr.toSpliced(2, 1, "pink", "cyan"); console.log(newArr); // ["red", "orange", "pink", "cyan", "green", "blue", "purple"] console.log(newArr[3]); // 'cyan' console.log(arr[3]); // 'green'
正式的 shebang 支持
Shebang 是旧式 Unix 术语,表示井号后跟一个感叹号:#!(其中 “bang” 是感叹号的俚语)。
#!/bin/bash echo "Hello, world!"
您可以使用 ./hello.sh 直接运行上面代码。
您也可以在 JavaScript 中执行类似操作:
#!/usr/bin/env node console.log("Hello, world!");
上面例子告诉操作系统使用 node 程序来运行此脚本。只需键入 ./hello.js 即可运行它。如果没有 #!是无法运行的。
Shebang 支持是规范中已经实现并在多种情境下非正式采用的特性之一。
Symbol 作为 WeakMap 的键
ES14 中的最后一个新功能是 Symbol 可以作为 WeakMap 的键使用。在这之前,WeakMap 仅允许对象作为键值,新特性更容易创建和共享 key。
var map = new WeakMap(); // 创建一个弱映射 function useSymbol(symbol){ doSomethingWith(symbol); var called = map.get(symbol) || 0
上面的例子允许从外部调用者调用计数器,并在不再有引用时释放映射条目。代码本身无法知道何时不再需要引用,如果使用普通的 Map,将会导致内存泄漏。这是因为即使在调用它的客户端不再需要引用时,代码仍然会保留对该引用的持有。在这种情况下使用 WeakMap,可以确保垃圾回收在不再存在对键符号的引用时删除映射条目。
总结
虽然 ES14 的规范刚发布不久,但是本文提到新增的数组 api 已经得到了主流浏览器支持。Chrome 110、Safari 16.3、Node.js 20 和 Deno1.31 都支持这四种新方法。