Lodash源码阅读-difference

Lodash 源码阅读-difference

概述

difference 函数是 Lodash 中用于计算数组差集的工具函数。它接收多个数组作为参数,返回一个新数组,其中包含存在于第一个数组中但不存在于其他数组中的元素。差集运算在数据处理、过滤和比较场景中非常有用。

前置学习

依赖函数

  • baseRest:一个转换函数,将剩余参数转换为数组并传递给目标函数
  • isArrayLikeObject:检查值是否为类数组对象(既像数组又是对象,如真实数组、arguments 对象等)
  • baseDifference:实现差集运算的核心函数,处理实际的差集计算逻辑
  • baseFlatten:将嵌套数组扁平化到指定深度的工具函数

技术知识

  • 数组操作:差集等集合运算的基本概念
  • 柯里化与函数组合:Lodash 中函数式编程技巧
  • 剩余参数处理:处理不定数量参数的技术
  • 数组扁平化:处理嵌套数组的方法
  • 类型检查:JavaScript 中的类型判断技巧

源码实现

js 复制代码
var difference = baseRest(function (array, values) {
  return isArrayLikeObject(array)
    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
    : [];
});

实现思路

difference 函数的实现思路非常简洁但功能强大:

  1. 使用 baseRest 将函数转换为接收剩余参数的形式,并将第一个参数视为源数组,其余参数作为要排除的值
  2. 检查源数组是否为类数组对象,确保输入有效
  3. 使用 baseFlatten 将所有排除值数组扁平化为一个单一的一维数组
  4. 调用 baseDifference 计算第一个数组与扁平化后的排除值数组之间的差集
  5. 如果源数组不是类数组对象,直接返回空数组作为默认结果

源码解析

函数包装与参数处理

js 复制代码
var difference = baseRest(function (array, values) {
  // ...
});

这里使用了 baseRest 函数来包装内部实现。baseRest 类似于 ES6 的剩余参数语法,它将 difference 接收到的所有参数转换成两部分:

  • array:第一个参数,表示要检查的数组
  • values:剩余的所有参数,表示要排除的数组集合

这种设计使 difference 函数可以接受任意数量的数组参数,形如:_.difference(array, values1, values2, ...)

类型检查与边界情况处理

js 复制代码
return isArrayLikeObject(array)
  ? /* 执行差集计算 */
  : [];

函数首先检查 array 是否为类数组对象。这个检查确保了:

  1. 输入参数是对象类型(排除原始值)
  2. length 属性且是非负整数
  3. 不是函数类型

如果第一个参数不是类数组对象,函数直接返回空数组,避免后续处理中的错误。这是处理边界情况的一种优雅方式。

扁平化处理

js 复制代码
baseFlatten(values, 1, isArrayLikeObject, true);

对于 values 参数(剩余的所有数组),函数使用 baseFlatten 进行扁平化处理:

  • values:要扁平化的数组集合
  • 1:扁平化深度为 1,只处理一层嵌套
  • isArrayLikeObject:只扁平化类数组对象
  • true:开启严格模式,只包含通过谓词检查的元素

这一步将所有要排除的数组参数合并成一个一维数组,为差集计算做准备。

差集计算

js 复制代码
baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true));

最后,函数调用 baseDifference 执行实际的差集运算:

  • 第一个参数是源数组 array
  • 第二个参数是扁平化后的所有排除值

baseDifference 会返回一个新数组,其中包含存在于 array 但不存在于扁平化后的 values 中的所有元素。

总结

difference 函数展示了 Lodash 实现函数式工具的精髓:通过组合多个专注于单一任务的小函数,构建出功能强大且易用的高阶函数。这个函数巧妙地结合了:

  1. 函数式设计 :使用 baseRest 实现不定参数处理,符合函数式编程思想
  2. 边界情况处理:通过类型检查确保函数健壮性
  3. 数据转换:使用扁平化处理简化数据结构
  4. 复用核心逻辑 :将核心计算逻辑委托给专用的 baseDifference 函数

从实现上看,difference 考虑了性能和易用性的平衡,通过类型检查减少不必要的计算,同时支持多数组差集运算,为用户提供了灵活的数组差集计算工具。

相关推荐
花生侠23 分钟前
记录:前端项目使用pnpm+husky(v9)+commitlint,提交代码格式化校验
前端
猿榜24 分钟前
魔改编译-永久解决selenium痕迹(二)
javascript·python
阿幸软件杂货间28 分钟前
阿幸课堂随机点名
android·开发语言·javascript
一涯30 分钟前
Cursor操作面板改为垂直
前端
我要让全世界知道我很低调37 分钟前
记一次 Vite 下的白屏优化
前端·css
threelab37 分钟前
three案例 Three.js波纹效果演示
开发语言·javascript·ecmascript
1undefined239 分钟前
element中的Table改造成虚拟列表,并封装成hooks
前端·javascript·vue.js
蓝倾1 小时前
淘宝批量获取商品SKU实战案例
前端·后端·api
comelong1 小时前
Docker容器启动postgres端口映射失败问题
前端