各位听众,大家好!今天咱们来聊聊JavaScript中Array.prototype.find()
和Array.prototype.findIndex()
这两个好兄弟,它们可是数组查找界的小能手,能帮你快速找到符合你心意的第一个元素。准备好了吗?咱们这就开始!
开场白:数组里寻宝记
想象一下,你是一个寻宝猎人,手里拿着一张藏宝图(数组),藏宝图上画着各种各样的宝藏(数组元素)。你的任务是找到符合特定描述的第一个宝藏。find()
和findIndex()
就像你的寻宝工具,能帮你高效完成任务。
find()
:找到你想要的那个“它”
find()
方法的作用是:找到数组中第一个满足提供的测试函数的元素的值。否则返回 undefined
。 简单来说,就是找到你想要的那个“它”,如果没找到,就告诉你“不存在”。
语法:
array.find(callback(element[, index[, array]])[, thisArg])
callback
:为你定义的测试函数,对数组中的每个元素执行。element
:当前被处理的元素。index
(可选):当前被处理元素的索引。array
(可选):调用find()
的数组本身。
thisArg
(可选):执行callback
时用作this
的值。
举个栗子:
const numbers = [5, 12, 8, 130, 44];
const found = numbers.find(element => element > 10);
console.log(found); // 输出: 12
在这个例子中,我们想找到数组numbers
中第一个大于10的数字。find()
方法遍历数组,当遇到12时,element > 10
返回true
,于是find()
就停下来,返回12。
再来一个栗子,这次是对象数组:
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
const result = inventory.find(fruit => fruit.name === 'cherries');
console.log(result); // 输出: {name: 'cherries', quantity: 5}
这次,我们想找到名字是’cherries’的水果。find()
找到了,并返回了整个对象。
找不到怎么办?
const numbers = [1, 2, 3, 4, 5];
const found = numbers.find(element => element > 10);
console.log(found); // 输出: undefined
如果数组中没有满足条件的元素,find()
会返回undefined
。
findIndex()
:找到“它”的位置
findIndex()
方法的作用是:找到数组中第一个满足提供的测试函数的元素的索引。否则返回 -1
。 它和find()
很像,只不过它不返回元素的值,而是返回元素的索引(位置)。如果找不到,就告诉你“-1”,代表“查无此人”。
语法:
array.findIndex(callback(element[, index[, array]])[, thisArg])
参数和find()
完全一样。
举个栗子:
const numbers = [5, 12, 8, 130, 44];
const foundIndex = numbers.findIndex(element => element > 10);
console.log(foundIndex); // 输出: 1
这次,我们想找到数组numbers
中第一个大于10的数字的索引。findIndex()
找到了12,它的索引是1,所以返回1。
对象数组的栗子:
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
const resultIndex = inventory.findIndex(fruit => fruit.name === 'cherries');
console.log(resultIndex); // 输出: 2
我们想找到名字是’cherries’的水果的索引。findIndex()
找到了,它的索引是2,所以返回2。
找不到怎么办?
const numbers = [1, 2, 3, 4, 5];
const foundIndex = numbers.findIndex(element => element > 10);
console.log(foundIndex); // 输出: -1
如果数组中没有满足条件的元素,findIndex()
会返回-1。
find()
vs findIndex()
:选择困难症?
现在你可能有点懵,find()
和findIndex()
这么像,我该选哪个呢? 别慌,我来帮你分析一下:
特性 | find() |
findIndex() |
---|---|---|
返回值 | 满足条件的第一个元素的值。找不到返回undefined |
满足条件的第一个元素的索引。找不到返回-1 |
用途 | 需要元素的值时 | 需要元素的索引时 |
应用场景 | 查找某个具体对象,例如查找用户信息 | 删除数组中的特定元素(需要索引) |
总结:
- 如果你需要元素的值,就用
find()
。 - 如果你需要元素的索引,就用
findIndex()
。
进阶用法:thisArg
参数
thisArg
参数允许你指定callback
函数中this
的值。 这在某些情况下很有用,尤其是在你使用类或对象的方法作为callback
时。
举个栗子:
class Counter {
constructor() {
this.count = 0;
}
isGreaterThan(value) {
this.count++;
return value > this.threshold;
}
findFirstGreaterThan(array, threshold) {
this.threshold = threshold;
return array.find(this.isGreaterThan, this);
}
findIndexFirstGreaterThan(array, threshold) {
this.threshold = threshold;
return array.findIndex(this.isGreaterThan, this);
}
}
const counter = new Counter();
const numbers = [1, 5, 10, 15, 20];
const found = counter.findFirstGreaterThan(numbers, 12);
const foundIndex = counter.findIndexFirstGreaterThan(numbers, 12);
console.log(found); // 输出: 15
console.log(foundIndex); // 输出: 3
console.log(counter.count); // 输出:2 (因为find和findIndex只遍历到满足条件的元素为止)
在这个例子中,我们定义了一个Counter
类,它有一个isGreaterThan
方法,用于判断一个值是否大于某个阈值。我们使用thisArg
参数将this
指向Counter
实例,这样isGreaterThan
方法才能访问this.threshold
。
注意事项:
find()
和findIndex()
在找到第一个满足条件的元素后就会停止遍历,不会继续查找。- 如果数组是空的,
find()
和findIndex()
会立即返回undefined
或-1
。 find()
和findIndex()
不会改变原始数组。
兼容性:
find()
和findIndex()
是ES6中新增的方法,一些老版本的浏览器可能不支持。 你可以使用polyfill来解决兼容性问题。
一个简单的polyfill:
if (!Array.prototype.find) {
Array.prototype.find = function(callback/*, thisArg*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.find called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (callback.call(thisArg, value, i, list)) {
return value;
}
}
return undefined;
};
}
if (!Array.prototype.findIndex) {
Array.prototype.findIndex = function(predicate) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (typeof predicate !== 'function') {
throw new TypeError(predicate + ' is not a function');
}
var thisArg = arguments[1];
for (var k = 0; k < len; k++) {
if (k in o) {
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
}
}
return -1;
};
}
实战演练:
假设你正在开发一个电商网站,你需要根据商品ID找到商品信息。
const products = [
{ id: 1, name: 'T-shirt', price: 20 },
{ id: 2, name: 'Jeans', price: 50 },
{ id: 3, name: 'Shoes', price: 80 }
];
function findProductById(productId) {
return products.find(product => product.id === productId);
}
const product = findProductById(2);
console.log(product); // 输出: { id: 2, name: 'Jeans', price: 50 }
再来一个,假设你需要删除购物车中某个商品。
let cart = [
{ id: 1, name: 'T-shirt', quantity: 2 },
{ id: 2, name: 'Jeans', quantity: 1 },
{ id: 3, name: 'Shoes', quantity: 1 }
];
function removeProductFromCart(productId) {
const index = cart.findIndex(item => item.id === productId);
if (index !== -1) {
cart.splice(index, 1);
}
}
removeProductFromCart(2);
console.log(cart); // 输出: [ { id: 1, name: 'T-shirt', quantity: 2 }, { id: 3, name: 'Shoes', quantity: 1 } ]
总结:
find()
和findIndex()
是JavaScript数组中非常有用的方法,它们能帮助你快速找到满足条件的第一个元素或元素的索引。 掌握它们,能让你的代码更加简洁高效。
课后练习:
- 创建一个包含学生对象的数组,每个学生对象包含
name
和score
属性。 - 使用
find()
找到第一个成绩大于80分的学生。 - 使用
findIndex()
找到第一个成绩不及格的学生(成绩小于60分)的索引。
好了,今天的讲座就到这里。希望大家能掌握find()
和findIndex()
的用法,在实际开发中灵活运用。 下次有机会再和大家分享其他有趣的JavaScript知识! 拜拜!