各位观众老爷,大家好!我是你们的老朋友,人称“码农界的段子手”的程序猿小李。今天咱们不聊八卦,来点实在的,扒一扒 JavaScript 数组里那个不太为人熟知,但关键时刻能救命的 findLast 方法。
咱们都知道,JavaScript 数组的 find 方法是从头到尾找符合条件的元素,找到第一个就收工。但有时候,我们需要从后往前找,比如查找数组中最后一个出现的某个元素,这时候 find 就抓瞎了。别慌,findLast 就是来解决这个问题的!
开胃小菜:find 方法回顾
在深入 findLast 之前,咱们先简单回顾一下 find 方法,温故而知新嘛。
find 方法的基本语法:
array.find(callback(element[, index[, array]])[, thisArg])
callback:一个用来测试数组中每个元素的函数。接受三个参数:element:当前正在处理的元素。index(可选):当前正在处理的元素的索引。array(可选):调用了find的数组本身。
thisArg(可选):执行callback时用作this的值。
find 方法会遍历数组,直到找到第一个使 callback 返回 true 的元素,然后返回该元素的值。如果没找到,就返回 undefined。
举个栗子:
const numbers = [5, 12, 8, 130, 44];
const found = numbers.find(element => element > 10);
console.log(found); // 输出: 12
这个例子很简单,find 找到了第一个大于 10 的元素 12,然后就屁颠屁颠地返回了。
主角登场:findLast 方法闪亮登场
好了,热身完毕,现在让咱们的主角 findLast 隆重登场!
findLast 方法和 find 方法长得几乎一模一样,就像孪生兄弟,但它们的搜索方向是相反的。findLast 从数组的末尾开始向前查找,找到第一个符合条件的元素,然后返回该元素的值。如果没找到,同样返回 undefined。
findLast 方法的基本语法:
array.findLast(callback(element[, index[, array]])[, thisArg])
参数和 find 方法完全相同,这里就不再赘述了。
代码实战:findLast 的各种用法
光说不练假把式,咱们直接上代码,看看 findLast 到底有多好用。
场景一:查找数组中最后一个偶数
const numbers = [5, 12, 8, 130, 44, 7, 22];
const lastEven = numbers.findLast(element => element % 2 === 0);
console.log(lastEven); // 输出: 22
在这个例子中,findLast 从数组的末尾开始查找,找到了最后一个偶数 22,然后就返回了。如果用 find 的话,结果会是 12。
场景二:查找数组中最后一个长度大于 5 的字符串
const words = ["apple", "banana", "kiwi", "strawberry", "orange", "grapefruit"];
const lastLongWord = words.findLast(word => word.length > 5);
console.log(lastLongWord); // 输出: "grapefruit"
这个例子展示了 findLast 在字符串数组中的应用。它找到了最后一个长度大于 5 的字符串 "grapefruit"。
场景三:结合索引 index 使用
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const lastNumberBeforeFive = numbers.findLast((element, index) => element > 0 && index < 5);
console.log(lastNumberBeforeFive); // 输出: 4
这个例子展示了如何在 callback 函数中使用索引 index。findLast 找到了最后一个索引小于 5 且大于 0 的元素 4。
场景四:使用 thisArg 参数
const numbers = [1, 2, 3, 4, 5];
const context = { threshold: 3 };
const lastNumberGreaterThanThreshold = numbers.findLast(function(element) {
return element > this.threshold;
}, context);
console.log(lastNumberGreaterThanThreshold); // 输出: 5
这个例子展示了如何使用 thisArg 参数来指定 callback 函数中的 this 值。findLast 找到了最后一个大于 context.threshold (即 3) 的元素 5。
findLastIndex 方法:查找元素的索引
除了 findLast 方法,还有一个和它配套的 findLastIndex 方法。findLastIndex 方法和 findLast 方法类似,也是从数组的末尾开始向前查找,但它返回的是第一个符合条件的元素的索引,而不是元素本身。如果没找到,就返回 -1。
findLastIndex 方法的基本语法:
array.findLastIndex(callback(element[, index[, array]])[, thisArg])
参数和 findLast 方法完全相同。
代码实战:findLastIndex 的各种用法
场景一:查找数组中最后一个偶数的索引
const numbers = [5, 12, 8, 130, 44, 7, 22];
const lastEvenIndex = numbers.findLastIndex(element => element % 2 === 0);
console.log(lastEvenIndex); // 输出: 6 (22的索引)
这个例子中,findLastIndex 返回了最后一个偶数 22 的索引 6。
场景二:查找数组中最后一个长度大于 5 的字符串的索引
const words = ["apple", "banana", "kiwi", "strawberry", "orange", "grapefruit"];
const lastLongWordIndex = words.findLastIndex(word => word.length > 5);
console.log(lastLongWordIndex); // 输出: 5 ("grapefruit"的索引)
这个例子展示了 findLastIndex 在字符串数组中的应用。它返回了最后一个长度大于 5 的字符串 "grapefruit" 的索引 5。
findLast 和 findLastIndex 的兼容性问题
需要注意的是,findLast 和 findLastIndex 方法是 ES2023 才引入的,这意味着在一些老旧的浏览器或环境中可能不支持这两个方法。
如果需要在旧环境中使用这两个方法,可以使用 polyfill 来进行兼容。以下是一个简单的 polyfill 实现:
if (!Array.prototype.findLast) {
Array.prototype.findLast = function(callback, thisArg) {
if (this == null) {
throw new TypeError('Array.prototype.findLast called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function');
}
const list = Object(this);
const length = list.length >>> 0;
const thisValue = arguments.length > 1 ? thisArg : undefined;
for (let i = length - 1; i >= 0; i--) {
if (callback.call(thisValue, list[i], i, list)) {
return list[i];
}
}
return undefined;
};
}
if (!Array.prototype.findLastIndex) {
Array.prototype.findLastIndex = function(callback, thisArg) {
if (this == null) {
throw new TypeError('Array.prototype.findLastIndex called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function');
}
const list = Object(this);
const length = list.length >>> 0;
const thisValue = arguments.length > 1 ? thisArg : undefined;
for (let i = length - 1; i >= 0; i--) {
if (callback.call(thisValue, list[i], i, list)) {
return i;
}
}
return -1;
};
}
这段代码首先检查 Array.prototype 上是否已经存在 findLast 和 findLastIndex 方法,如果不存在,则添加相应的实现。
find、findLast、findIndex 和 findLastIndex 的比较
为了更好地理解这四个方法,咱们用一个表格来总结一下它们的区别:
| 方法 | 描述 | 返回值 | 搜索方向 |
|---|---|---|---|
find |
查找数组中第一个符合条件的元素 | 符合条件的元素的值,如果没有找到则返回 undefined |
从头到尾 |
findLast |
查找数组中最后一个符合条件的元素 | 符合条件的元素的值,如果没有找到则返回 undefined |
从尾到头 |
findIndex |
查找数组中第一个符合条件的元素的索引 | 符合条件的元素的索引,如果没有找到则返回 -1 | 从头到尾 |
findLastIndex |
查找数组中最后一个符合条件的元素的索引 | 符合条件的元素的索引,如果没有找到则返回 -1 | 从尾到头 |
总结:findLast 和 findLastIndex 的价值
findLast 和 findLastIndex 方法虽然看起来不起眼,但在某些场景下却能发挥巨大的作用。它们可以帮助我们更方便地从后向前查找数组中的元素,避免手动遍历数组的麻烦。
应用场景举例
- 日志分析: 在一个日志数组中,查找最近一次发生的错误。
- 撤销操作: 在一个操作历史数组中,查找最后一次执行的操作。
- 版本控制: 在一个版本历史数组中,查找最近一次发布的版本。
总而言之,findLast 和 findLastIndex 是 JavaScript 数组中非常有用的两个方法,掌握它们可以提高我们的编程效率,让代码更加简洁易懂。
好了,今天的讲座就到这里。希望大家通过今天的学习,能够对 findLast 和 findLastIndex 方法有一个更深入的了解。记住,技术的世界是广阔的,只有不断学习,才能不断进步!咱们下期再见!