Lodash 源码阅读-uniq
概述
uniq
函数用于创建一个数组的去重版本,只保留数组中每个元素的第一次出现。这个函数使用 SameValueZero
进行相等性比较,结果数组中元素的顺序取决于它们在原数组中首次出现的位置。
前置学习
函数依赖:
baseUniq
: 不支持迭代器简写形式的uniq
函数的基本实现。
技术知识:
- JavaScript 的类型转换
- JavaScript 中的相等性比较(
SameValueZero
) - 数组去重算法
- 哈希表的使用
源码实现
js
function uniq(array) {
return array && array.length ? baseUniq(array) : [];
}
实现思路
uniq
函数的实现非常简洁,主要逻辑委托给了 baseUniq
函数。首先进行了参数验证:检查 array
是否存在且有长度,如果是则调用 baseUniq
处理数组去重,否则返回空数组。而真正的去重逻辑在 baseUniq
函数中实现。
源码解析
让我们逐行解析 uniq
函数:
js
function uniq(array) {
函数定义,接收一个参数 array
,这是需要去重的数组。
js
return array && array.length ? baseUniq(array) : [];
这行代码做了两件事:
- 检查
array
是否存在且有长度(array && array.length
) - 根据检查结果:
- 如果
array
存在且有长度,则调用baseUniq(array)
执行去重操作 - 如果
array
不存在或长度为 0,则直接返回空数组[]
- 如果
这样的处理方式确保了函数的健壮性,避免了对无效输入的处理。
uniq
函数的核心去重逻辑委托给了内部函数 baseUniq
。当 uniq
调用 baseUniq(array)
时,它仅传递了原数组作为参数,没有提供 iteratee
或 comparator
参数。
在这种调用模式下,baseUniq
的核心任务是实现基于 SameValueZero
相等性比较的数组去重,并会根据数组的大小(length >= LARGE_ARRAY_SIZE
)选择不同的性能优化策略(如使用 Set
、SetCache
或直接遍历比较)。虽然 baseUniq
内部有处理 iteratee
和 comparator
的逻辑分支,但对于 uniq
的直接调用,这些分支不会被激活。
总而言之,uniq
依赖 baseUniq
来完成实际的去重工作,通过提供简化的 API 接口使开发者能够方便地进行数组去重操作。这种设计让 uniq
能够保持简洁的接口,同时在内部利用功能更强大的 baseUniq
实现高效的去重处理。
总结
uniq
函数是 Lodash 提供的一个简单易用但功能强大的数组去重工具。它的特点包括:
- 简单的 API 设计:只需传入一个数组参数即可使用
- 健壮的参数处理 :能够处理各种边缘情况,如空数组、
null
、undefined
等 - 高效的实现:针对大数组提供了优化
- 正确的语义 :使用
SameValueZero
进行相等性比较,正确处理特殊值如NaN
和-0
在实际开发中,uniq
函数可以用于去除数组中的重复元素,简化数据处理流程,是数组操作中常用的工具函数。
从设计模式角度看,uniq
采用了委托模式,将具体实现委托给 baseUniq
函数,这种设计使得 API 保持简洁的同时,内部实现可以更加灵活和高效。