jsfind 方法是 JavaScript 数组原型上的内置查找方法,作用是遍历数组,找到第一个满足回调函数判断条件的元素,并且直接返回这个元素本身,如果整个数组遍历完成都没有匹配项,就返回 undefined,它属于 ES6 新增的数组迭代方法,很多新手会把它和 indexOf filter 混淆,要记住 find 返回的是元素不是下标,而且只返回第一个命中项,不会继续往后遍历,之所以设计这个方法,是因为传统 for 循环查找元素需要自己写循环判断,还要手动 break 停止遍历,代码冗余,jsfind 方法把遍历和终止逻辑封装好,开发者只需要编写判断条件回调,使用的时候先拿到目标数组,调用 find 方法传入回调函数,回调里面写判断规则,匹配成功就拿到对应元素,没有匹配就得到 undefined,熟练掌握之后可以大幅简化数组对象查找业务,比如根据 id 查找用户 根据编号查找商品这类场景非常常用。
基础语法结构
array.find (callback, thisArg)
callback 回调函数,支持三个参数
currentValue 当前正在遍历的数组元素 必选
index 当前元素的下标 可选
arr 原数组本身 可选
thisArg 可选参数,用来指定回调函数内部 this 指向,如果不传默认是 undefined,严格模式下 this 不会指向 window
核心特性清单
1 只返回第一个符合条件的元素,找到之后立刻停止遍历,后面元素不再执行回调
2 返回值是元素本身,不是元素索引下标,这点和 findIndex 区分
3 如果没有任何元素满足条件,返回 undefined
4 不会修改原数组,属于纯读取遍历,不会改变数组内部数据
5 空数组调用 find,直接返回 undefined,回调不会执行
6 数组里面如果存在 undefined 元素,并且条件匹配,依然会正常返回这个 undefined 元素,要和没有匹配的 undefined 做好区分
相关方法对比表格
| 方法 | 返回结果 | 是否停止遍历 | 适用场景 |
|---|---|---|---|
| find | 匹配元素本身 | 找到第一个就停止 | 拿到目标对象数据 |
| findIndex | 匹配元素下标 | 找到第一个就停止 | 只需要获取索引位置 |
| filter | 全部匹配元素组成新数组 | 完整遍历全部元素 | 需要获取所有符合条件的数据 |
| indexOf | 元素下标 | 找到第一个就停止 | 基础类型精确查找 |
深度运行原理
jsfind 底层执行流程是从数组下标 0 开始,依次取出每一项传入回调,回调返回布尔值 true 的时候,代表条件成立,立刻终止循环,把当前元素作为 find 的返回值,如果回调返回 false,继续读取下一项,一直遍历到数组末尾,全部都是 false,最终返回 undefined。
需要注意稀疏数组的特殊行为,对于数组空位,jsfind 会跳过空位,不会把空位传入回调函数,这个是很多老代码容易踩坑的地方。
回调函数里面如果做异步操作,比如请求接口,find 不会等待异步结果,因为 find 是同步迭代方法,异步判断无法正常工作,这个是高频误区。
典型使用示例
普通对象数组查找,用户数组里面根据 id 查找用户对象,回调里面写 return item.id === 1001,匹配成功就返回这个用户对象,失败返回 undefined。
基础类型数组查找,数字数组查找第一个大于 10 的数字,回调写 return item > 10。
使用 thisArg 指定 this,适合需要绑定外部对象的业务场景。
常见坑点说明
第一坑 把 find 当成 filter,想要拿到全部匹配元素,结果只拿到第一项,需要全部匹配要改用 filter
第二坑 混淆 find 和 findIndex,需要下标的时候误用 find,拿到对象之后还要自己找下标,增加多余代码
第三坑 回调没有 return,回调默认返回 undefined,也就是永远条件不成立,最终 find 一直返回 undefined,这个是新手最常见错误
第四坑 在回调里面写异步代码,误以为 find 会等待接口返回,实际同步执行完毕,判断结果不准确
第五坑 判断条件使用宽松等于和严格等于没有区分,数字和字符串类型不匹配,导致查找失败
【常见问题】
问题 1 jsfind 方法如果没有找到匹配元素返回什么
回答 1 jsfind 方法遍历完整数组之后没有任何元素满足回调条件,返回 undefined,开发的时候经常需要对这个返回值做判断,避免后续读取对象属性报错。
问题 2 jsfind 方法和 findIndex 方法核心差别是什么
回答 1 jsfind 方法返回的是匹配到的元素本身,findIndex 返回的是该元素的下标,两者都是找到第一个匹配项之后停止遍历,业务需要数据本身就用 jsfind,只需要位置下标就使用 findIndex。
问题 3 jsfind 方法可以用来异步查找吗
回答 1 jsfind 属于同步迭代 API,回调内部如果写异步请求,jsfind 不会等待异步结果完成,回调立刻返回,无法实现异步条件判断,异步查找业务不能直接使用 jsfind 方法。
【免责申明】
本文内容仅作为 JavaScript jsfind 方法学习参考,不同浏览器以及 js 运行环境对数组迭代方法存在版本兼容差异,ES6 以下旧环境需要做 polyfill 兼容处理,本文不对项目上线后出现的兼容异常业务损失承担相关责任。


