实现findIndex方法
手写实现数组的findIndex方法,返回第一个满足条件的元素索引
问题
findIndex 是 ES6 中数组的一个方法,用于查找数组中第一个满足测试函数条件的元素,并返回该元素的索引。如果没有找到满足条件的元素,则返回 -1。
我们需要手动实现这个方法,支持:
- 接收一个回调函数作为参数
- 回调函数接收三个参数:当前元素、当前索引、原数组
- 支持传入 thisArg 改变回调函数的 this 指向
- 返回第一个满足条件的元素索引,否则返回 -1
解答
/**
* 实现 Array.prototype.findIndex 方法
* @param {Function} callback - 测试函数
* @param {*} thisArg - 可选,执行 callback 时的 this 值
* @returns {number} 返回第一个满足条件的元素索引,否则返回 -1
*/
Array.prototype.myFindIndex = function(callback, thisArg) {
// 检查调用对象是否为 null 或 undefined
if (this == null) {
throw new TypeError('Array.prototype.myFindIndex called on null or undefined');
}
// 检查 callback 是否为函数
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 将调用对象转换为对象
const obj = Object(this);
// 获取数组长度,使用无符号右移确保为非负整数
const len = obj.length >>> 0;
// 遍历数组
for (let i = 0; i < len; i++) {
// 检查索引是否存在(处理稀疏数组)
if (i in obj) {
// 调用回调函数,传入当前元素、索引和原数组
// 使用 call 绑定 thisArg
if (callback.call(thisArg, obj[i], i, obj)) {
return i; // 找到满足条件的元素,返回索引
}
}
}
// 没有找到满足条件的元素,返回 -1
return -1;
};
使用示例
// 示例1:查找第一个大于 10 的数字的索引
const numbers = [5, 8, 12, 15, 20];
const index1 = numbers.myFindIndex(num => num > 10);
console.log(index1); // 输出: 2
// 示例2:查找第一个偶数的索引
const numbers2 = [1, 3, 5, 8, 9];
const index2 = numbers2.myFindIndex(num => num % 2 === 0);
console.log(index2); // 输出: 3
// 示例3:未找到满足条件的元素
const numbers3 = [1, 3, 5, 7];
const index3 = numbers3.myFindIndex(num => num > 10);
console.log(index3); // 输出: -1
// 示例4:使用索引参数
const arr = ['a', 'b', 'c', 'd'];
const index4 = arr.myFindIndex((item, index) => index === 2);
console.log(index4); // 输出: 2
// 示例5:使用 thisArg 参数
const threshold = {
min: 10,
max: 20
};
const numbers4 = [5, 15, 25, 30];
const index5 = numbers4.myFindIndex(function(num) {
return num >= this.min && num <= this.max;
}, threshold);
console.log(index5); // 输出: 1
// 示例6:查找对象数组
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 35 }
];
const index6 = users.myFindIndex(user => user.name === 'Bob');
console.log(index6); // 输出: 1
关键点
- 参数校验:需要检查 this 是否为 null/undefined,以及 callback 是否为函数类型
- 类型转换:使用
Object(this)将调用对象转换为对象,使用>>> 0确保长度为非负整数 - 遍历逻辑:使用 for 循环遍历数组,找到第一个满足条件的元素立即返回索引
- 稀疏数组处理:使用
in操作符检查索引是否存在,跳过空位 - this 绑定:使用
call方法将 thisArg 绑定到回调函数的 this 上 - 返回值:找到满足条件的元素返回索引,否则返回 -1
- 回调函数参数:回调函数接收三个参数:当前元素值、当前索引、原数组对象
目录