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
函数的实现思路非常简洁但功能强大:
- 使用
baseRest
将函数转换为接收剩余参数的形式,并将第一个参数视为源数组,其余参数作为要排除的值 - 检查源数组是否为类数组对象,确保输入有效
- 使用
baseFlatten
将所有排除值数组扁平化为一个单一的一维数组 - 调用
baseDifference
计算第一个数组与扁平化后的排除值数组之间的差集 - 如果源数组不是类数组对象,直接返回空数组作为默认结果
源码解析
函数包装与参数处理
js
var difference = baseRest(function (array, values) {
// ...
});
这里使用了 baseRest
函数来包装内部实现。baseRest
类似于 ES6 的剩余参数语法,它将 difference
接收到的所有参数转换成两部分:
array
:第一个参数,表示要检查的数组values
:剩余的所有参数,表示要排除的数组集合
这种设计使 difference
函数可以接受任意数量的数组参数,形如:_.difference(array, values1, values2, ...)
。
类型检查与边界情况处理
js
return isArrayLikeObject(array)
? /* 执行差集计算 */
: [];
函数首先检查 array
是否为类数组对象。这个检查确保了:
- 输入参数是对象类型(排除原始值)
- 有
length
属性且是非负整数 - 不是函数类型
如果第一个参数不是类数组对象,函数直接返回空数组,避免后续处理中的错误。这是处理边界情况的一种优雅方式。
扁平化处理
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 实现函数式工具的精髓:通过组合多个专注于单一任务的小函数,构建出功能强大且易用的高阶函数。这个函数巧妙地结合了:
- 函数式设计 :使用
baseRest
实现不定参数处理,符合函数式编程思想 - 边界情况处理:通过类型检查确保函数健壮性
- 数据转换:使用扁平化处理简化数据结构
- 复用核心逻辑 :将核心计算逻辑委托给专用的
baseDifference
函数
从实现上看,difference
考虑了性能和易用性的平衡,通过类型检查减少不必要的计算,同时支持多数组差集运算,为用户提供了灵活的数组差集计算工具。