Lodash源码阅读-indexOf

Lodash 源码阅读-indexOf

一、介绍

indexOf 是 Lodash 中用于在数组中查找元素的方法,它返回找到的第一个匹配元素的索引,如果没找到则返回 -1。与 JavaScript 原生的 Array.prototype.indexOf 类似,但 Lodash 版本提供了更好的兼容性和对 NaN 值的特殊处理。

前置学习

在深入理解 indexOf 函数之前,建议先了解以下相关概念:

  • baseIndexOf:Lodash 的内部查找函数

  • toInteger:Lodash 的整数转换函数

二、源码实现

js 复制代码
function indexOf(array, value, fromIndex) {
  var length = array == null ? 0 : array.length;
  if (!length) {
    return -1;
  }
  var index = fromIndex == null ? 0 : toInteger(fromIndex);
  if (index < 0) {
    index = nativeMax(length + index, 0);
  }
  return baseIndexOf(array, value, index);
}

三、实现原理

1. 整体思路

indexOf 函数的实现思路可以概括为:

  1. 处理边界情况(空数组、null/undefined)
  2. 处理起始位置参数(默认值、负数索引)
  3. 调用 baseIndexOf 执行实际的查找逻辑
  4. 返回找到的索引或 -1

2. 参数说明

  • array:要搜索的数组
  • value:要查找的值
  • fromIndex:开始搜索的位置(索引),可选

3. 逐行解析

js 复制代码
var length = array == null ? 0 : array.length;
if (!length) {
  return -1;
}
  • 获取数组长度,如果数组为 nullundefined,则设为 0
  • 如果数组长度为 0,直接返回 -1(优化处理)
js 复制代码
var index = fromIndex == null ? 0 : toInteger(fromIndex);
if (index < 0) {
  index = nativeMax(length + index, 0);
}
  • 处理 fromIndex 参数
  • 如果未提供,默认为 0
  • 使用 toInteger 函数确保 fromIndex 是整数
  • 如果是负数,则从数组末尾开始计算位置,且不小于 0
js 复制代码
return baseIndexOf(array, value, index);
  • 调用 baseIndexOf 执行实际的查找逻辑

四、使用示例

js 复制代码
// 基本使用
_.indexOf([1, 2, 3, 4], 2); // => 1
_.indexOf([1, 2, 3, 4], 5); // => -1

// 指定起始位置
_.indexOf([1, 2, 3, 1, 2, 3], 2, 2); // => 4

// 处理 NaN 值(这是与原生 indexOf 的主要区别)
_.indexOf([1, NaN, 3], NaN); // => 1
[1, NaN, 3].indexOf(NaN); // => -1 (原生方法找不到 NaN)

// 负数索引
_.indexOf([1, 2, 3, 4], 2, -2); // => -1 (从倒数第二个元素开始查找)
_.indexOf([1, 2, 3, 4], 3, -2); // => 2

// 处理 null/undefined
_.indexOf(null, 1); // => -1
_.indexOf(undefined, 1); // => -1

五、与原生 indexOf 的区别

  1. NaN 处理 :Lodash 的 indexOf 可以找到数组中的 NaN 值,而原生 Array.prototype.indexOf 不行

  2. 兼容性:Lodash 的实现考虑了更多的边界情况和浏览器兼容性问题

  3. fromIndex 处理:对负数索引的处理更加健壮

六、总结

  1. 安全的空值处理

    js 复制代码
    var length = array == null ? 0 : array.length;

    使用宽松相等检查 null 和 undefined,避免报错

  2. 模块化设计

    js 复制代码
    return baseIndexOf(array, value, index);

    将核心查找逻辑抽离到专门的函数中

  3. 负索引处理

    js 复制代码
    index = nativeMax(length + index, 0);

    确保负索引转换为有效的数组索引,且不小于 0

  4. 早期返回优化

    js 复制代码
    if (!length) {
      return -1;
    }

    对空数组进行快速处理,避免不必要的计算

相关推荐
码界奇点4 分钟前
基于Vue3与TypeScript的后台管理系统设计与实现
前端·javascript·typescript·vue·毕业设计·源代码管理
ashcn200110 分钟前
水滴按钮解析
前端·javascript·css
攀登的牵牛花10 分钟前
前端向架构突围系列 - 框架设计(五):契约继承原则
前端·架构
爱吃奶酪的松鼠丶17 分钟前
React长列表,性能优化。关于循环遍历的时候,key是用对象数据中的ID还是用索引
javascript·react.js·性能优化
xkxnq41 分钟前
第二阶段:Vue 组件化开发(第 17天)
javascript·vue.js·ecmascript
豆苗学前端1 小时前
你所不知道的前端知识,html篇(更新中)
前端·javascript·面试
一 乐1 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
zzjyr1 小时前
Webpack 生命周期原理深度解析
前端
xiaohe06011 小时前
💘 霸道女总裁爱上前端开发的我
前端·游戏开发·trae
sophie旭1 小时前
内存泄露排查之我的微感受
前端·javascript·性能优化