Array 实例方法 filter 的实现

Array.prototype.filter()

filter() 方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。 换句话说,它会筛选出原始数组中满足条件的元素,并将其组成一个新的数组返回。 filter() 不会改变原数组,但是传入的回调函数可以改变原数组。

语法

js 复制代码
filter(callbackFn) 
filter(callbackFn, thisArg)

参数

1、callbackFn:为数组中的每个元素执行的函数。它应该返回一个真值以将元素保留在结果数组中,否则返回一个假值。

该函数被调用时将传入以下参数:

  • element:数组中当前正在处理的元素。
  • index:正在处理的元素在数组中的索引。
  • array:调用了 filter() 的数组本身。

2、thisArg(可选):执行 callbackFn 时用作 this 的值。

返回值

返回给定数组的一部分的浅拷贝,其中只包括通过提供的函数实现的测试的元素。 如果没有元素通过测试,则返回一个空数组。

描述

filter() 方法是一个迭代方法。它为数组中的每个元素调用提供的 callbackFn 函数一次,并构造一个由所有返回真值的元素值组成的新数组。

callbackFn 仅在已分配值的数组索引处被调用。它不会在稀疏数组中的空槽处被调用。

请注意,在第一次调用 callbackFn之前,数组的长度已经被保存。因此:

  • 当开始调用 filter() 时,callbackFn 将不会访问超出数组初始长度的任何元素。
  • 对已访问索引的更改不会导致再次在这些元素上调用 callbackFn。
  • 如果数组中一个现有的、尚未访问的元素被 callbackFn 更改,则它传递给 callbackFn 的值将是该元素被修改后的值。被删除的元素则不会被访问

上述类型的并发修改经常导致难以理解的代码,通常应避免(特殊情况除外)。

filter() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。

实现 filter 方法

从上面 filter 描述总结实现 filter 时注意实现这三点。

  • 回调函数调用之前,数组的长度已经被保存。
  • 回调函数不会在稀疏数组中的空槽处被调用。
  • 返回值是所有真值的元素值组成的新数组。
js 复制代码
Array.prototype.myFilter = function (fun, context) {
    if (!Object.is(typeof fun, 'function')) {
        throw TypeError(`${typeof fun} is not a function`)
    }
    const newArr = []
    for (let i = 0, len = this.length; i < len; i++) {
        if (Object.hasOwn(this, i)) {  // 跳过稀疏数组
            const result = fun.call(context, this[i], i, this)
            if (result) {
                newArr.push(this[i])
            }
        }
    }
    return newArr
}

结语

到这里 Array 实例方法 filter 实现完成啦。

JavaScript 中的 Array 类型提供了一系列强大的实例方法。在 Array 实例方法实现系列专栏中,我将深入探讨一些常见的 Array 实例方法,解析它们的实现原理。

如果有错误或者不严谨的地方,请大家务必给予指正,十分感谢。欢迎大家在评论区中讨论。

相关推荐
我不吃饼干7 分钟前
倒反天罡,CSS 中竟然可以写 JavaScript
前端·javascript·css
张风捷特烈8 分钟前
每日一题 Flutter#11 | StatelessWidget 从诞生到 build 的流程
android·flutter·面试
10年前端老司机2 小时前
什么!纯前端也能识别图片中的文案、还支持100多个国家的语言
前端·javascript·vue.js
magic 2453 小时前
模拟 AJAX 提交 form 表单及请求头设置详解
前端·javascript·ajax
只喜欢赚钱的棉花没有糖8 小时前
http的缓存问题
前端·javascript·http
让梦想疯狂9 小时前
开源、免费、美观的 Vue 后台管理系统模板
前端·javascript·vue.js
葡萄糖o_o9 小时前
ResizeObserver的错误
前端·javascript·html
sunbyte10 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | AnimatedNavigation(动态导航)
前端·javascript·vue.js·tailwindcss
JustHappy11 小时前
啥是Hooks?为啥要用Hooks?Hooks该怎么用?像是Vue中的什么?React Hooks的使用姿势(下)
前端·javascript·react.js
江城开朗的豌豆11 小时前
Vue中Token存储那点事儿:从localStorage到内存的避坑指南
前端·javascript·vue.js