Array.prototype.findLast()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2022年8月.
findLast() 方法反向迭代数组,并返回满足提供的测试函数的第一个元素的值。如果没有找到对应元素,则返回 undefined。
如果你需要查找:
- 第一个匹配的元素,请使用
find()。 - 数组中最后一个匹配元素的索引,请使用
findLastIndex()。 - 某个值的索引,请使用
indexOf()。(它类似于findIndex(),但是会检查每个元素是否与值相等,而不是使用一个测试函数。) - 某个值是否存在该数组中,请使用
includes()。同样地,它会检查每个元素是否与该值相等,而不是使用一个测试函数。 - 是否有任意一个元素满足给定的测试函数,请使用
some()。
尝试一下
const array = [5, 12, 50, 130, 44];
const found = array.findLast((element) => element > 45);
console.log(found);
// 期望输出:130
语法
findLast(callbackFn)
findLast(callbackFn, thisArg)
参数
callbackFnthisArg可选-
执行
callbackFn时,用作this的值。详见迭代方法。
返回值
数组中满足提供的测试函数索引最高的元素;如果没有元素匹配,返回 undefined。
描述
findLast() 是一个迭代方法。该方法对数组每一个元素按降序(索引从大到小)执行 callbackFn 函数,直到 callbackFn 返回一个真值。然后 findLast() 返回该元素的值并停止遍历数组。如果 callbackFn 没有返回一个真值,则 findLast() 返回 undefined。
callbackFn 会被数组中的每个元素调用,而不仅仅是那些被赋值的元素。对于稀疏数组来说,空槽行为和 undefined 相同。
findLast() 方法是通用的。它只期望 this 值具有 length 属性和整数键的属性。
示例
>查找与元素属性匹配的数组中的最后一个对象
此示例展示了如何根据数组元素的属性创建测试。
const inventory = [
{ name: "apples", quantity: 2 },
{ name: "bananas", quantity: 0 },
{ name: "fish", quantity: 1 },
{ name: "cherries", quantity: 5 },
];
// 库存低时返回 true
function isNotEnough(item) {
return item.quantity < 2;
}
console.log(inventory.findLast(isNotEnough));
// { name: "fish", quantity: 1 }
使用箭头函数和解构
前面的示例可以使用箭头函数和对象解构重写如下:
const inventory = [
{ name: "apples", quantity: 2 },
{ name: "bananas", quantity: 0 },
{ name: "fish", quantity: 1 },
{ name: "cherries", quantity: 5 },
];
const result = inventory.findLast(({ quantity }) => quantity < 2);
console.log(result);
// { name: "fish", quantity: 1 }
查找数组中的最后一个素数
以下示例查找数组中的最后一个素数元素(如果没有素数,则返回 undefined):
function isPrime(n) {
if (n < 2) {
return false;
}
if (n % 2 === 0) {
return n === 2;
}
for (let factor = 3; factor * factor <= n; factor += 2) {
if (n % factor === 0) {
return false;
}
}
return true;
}
console.log([4, 6, 8, 12].findLast(isPrime)); // undefined,没有找到
console.log([4, 5, 7, 8, 9, 11, 12].findLast(isPrime)); // 11
备注:isPrime() 实现仅供演示。在实际应用中,为了避免重复计算,会使用大量记忆化的算法,例如埃拉托斯特尼筛法。
查找最近完成的任务
此示例演示了在处理按时间排序的数据时 findLast() 的一个实际应用场景。它从已按 timestamp 排序的列表中查找最近完成的任务。
const tasks = [
{ name: "搭建项目", completed: true, timestamp: 1609459200000 },
{ name: "编写测试", completed: false, timestamp: 1609545600000 },
{ name: "修复 bug #42", completed: true, timestamp: 1609632000000 },
{ name: "部署到预发环境", completed: true, timestamp: 1609718400000 },
{ name: "审查 PR", completed: false, timestamp: 1609804800000 },
];
const lastCompletedTask = tasks.findLast((task) => task.completed);
console.log(lastCompletedTask.name); // 部署到预发环境
这比对倒序数据使用 find() 更高效,因为它避免了创建新数组。
使用回调函数的第三个参数
如果你需要访问数组中的另一个元素,array 参数会非常有用,尤其是在没有现有的变量引用该数组时。以下示例首先使用 filter() 提取正数,然后使用 findLast() 查找小于其相邻元素的最后一个元素。
const numbers = [3, -1, 1, 4, 1, 5, 9, 2, 6];
const lastTrough = numbers
.filter((num) => num > 0)
.findLast((num, idx, arr) => {
// 如果没有 arr 参数,就无法轻松访问中间数组,除非将其保存到变量中。
if (idx > 0 && num >= arr[idx - 1]) return false;
if (idx < arr.length - 1 && num >= arr[idx + 1]) return false;
return true;
});
console.log(lastTrough); // 2
在稀疏数组上使用 findLast()
稀疏数组中的空槽被访问,并被视为 undefined。
// 声明一个在索引 2、3 和 4 处没有元素的数组
const array = [0, 1, , , , 5, 6];
// 显示所有的索引(不只包括那些被赋值的)
array.findLast((value, index) => {
console.log(`访问索引 ${index},值为 ${value}`);
return false;
});
// 访问索引 6,值为 6
// 访问索引 5,值为 5
// 访问索引 4,值为 undefined
// 访问索引 3,值为 undefined
// 访问索引 2,值为 undefined
// 访问索引 1,值为 1
// 访问索引 0,值为 0
// 显示所有的索引(包括已被删除的)
array.findLast((value, index) => {
// 在第一次迭代时删除值为 5 的元素
if (index === 6) {
console.log(`删除值为 array[5],其值为 ${array[5]}`);
delete array[5];
}
// 元素 5 在被删除后,仍会被访问
console.log(`访问索引 ${index},值为 ${value}`);
return false;
});
// 删除值为 array[5],其值为 5
// 访问索引 6,值为 6
// 访问索引 5,值为 undefined
// 访问索引 4,值为 undefined
// 访问索引 3,值为 undefined
// 访问索引 2,值为 undefined
// 访问索引 1,值为 1
// 访问索引 0,值为 0
在非数组对象上调用 findLast()
findLast() 方法读取 this 的 length 属性,然后访问每个键为小于 length 的非负整数的属性。
const arrayLike = {
length: 3,
0: 2,
1: 7.3,
2: 4,
3: 3, // 被 findLast() 忽略,因为 length 是 3
};
console.log(
Array.prototype.findLast.call(arrayLike, (x) => Number.isInteger(x)),
); // 4
规范
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-array.prototype.findlast> |
浏览器兼容性
参见
core-js中Array.prototype.findLast的 polyfillArray.prototype.findLast的 es-shims polyfill- 索引集合指南
ArrayArray.prototype.find()Array.prototype.findIndex()Array.prototype.findLastIndex()Array.prototype.includes()Array.prototype.filter()Array.prototype.every()Array.prototype.some()TypedArray.prototype.findLast()