JavaScript手动实现Array.prototype.filter方法

Array.prototype.filter 是 JavaScript 中非常常用的数组方法之一,它用于创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。下面是如何手动实现 filter 方法的示例:
Array.prototype.myFilter = function(callback, thisArg) {
if (this == null) {
throw new TypeError('Array.prototype.myFilter called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const array = Object(this);
const len = array.length >>> 0;
const result = [];
for (let i = 0; i < len; i++) {
if (i in array) {
const element = array[i];
if (callback.call(thisArg, element, i, array)) {
result.push(element);
}
}
}
return result;
};
// 使用示例
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.myFilter(function(num) {
return num % 2 === 0;
});
console.log(evenNumbers); // 输出: [2, 4]
代码解释:
-
参数检查:
- 首先检查
this是否为null或undefined,如果是,则抛出TypeError。 - 检查
callback是否为函数,如果不是,则抛出TypeError。
- 首先检查
-
处理数组:
- 使用
Object(this)将this转换为对象,确保处理的是数组或类数组对象。 - 使用
length >>> 0确保length是一个非负整数。
- 使用
-
遍历数组:
- 使用
for循环遍历数组的每个元素。 - 使用
in操作符检查当前索引是否存在于数组中(避免稀疏数组的问题)。 - 调用
callback函数,传入当前元素、索引和数组本身。如果callback返回true,则将当前元素添加到结果数组中。
- 使用
-
返回结果:
- 最后返回包含所有通过测试的元素的新数组。
注意事项:
filter方法不会改变原数组,而是返回一个新数组。callback函数可以接受三个参数:当前元素、当前索引和数组本身。thisArg参数用于指定callback函数中的this值。
性能考虑:
- 由于
filter方法会创建一个新数组,因此在处理非常大的数组时,可能会占用较多的内存。如果不需要保留原数组,可以考虑使用for循环或其他方法来减少内存开销。
这个实现方式与原生 filter 方法的行为基本一致,适用于大多数场景。