各位观众老爷,大家好!我是你们的老朋友,人称“码农界的段子手”的程序猿小李。今天咱们不聊八卦,来点实在的,扒一扒 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
方法有一个更深入的了解。记住,技术的世界是广阔的,只有不断学习,才能不断进步!咱们下期再见!