Lodash 源码阅读-take
概述
take
函数用于从数组开头提取指定数量的元素并返回新数组。与 drop
函数相反,drop
丢弃前面元素保留剩余部分,而 take
保留前面元素丢弃剩余部分。
前置学习
依赖函数
- baseSlice:底层数组切片函数,实现核心切片逻辑
- toInteger :将输入值转换为整数,处理
n
参数
技术知识
- 数组切片:创建数组子集的操作
- 参数默认值:通过条件判断设置默认参数
- 类型转换:处理不同类型输入
- 边界处理:处理空数组、负数等边界情况
源码实现
javascript
/**
* Creates a slice of `array` with `n` elements taken from the beginning.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to take.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
* _.take([1, 2, 3]);
* // => [1]
*
* _.take([1, 2, 3], 2);
* // => [1, 2]
*
* _.take([1, 2, 3], 5);
* // => [1, 2, 3]
*
* _.take([1, 2, 3], 0);
* // => []
*/
function take(array, n, guard) {
if (!(array && array.length)) {
return [];
}
n = guard || n === undefined ? 1 : toInteger(n);
return baseSlice(array, 0, n < 0 ? 0 : n);
}
实现思路
take
函数实现非常简单明了:首先检查输入数组是否有效,若无效则返回空数组;然后处理切片数量参数,确定默认值或转换为整数;最后调用 baseSlice
从数组开头提取指定数量的元素并返回。
源码解析
参数校验
javascript
if (!(array && array.length)) {
return [];
}
这行代码检查数组是否有效:
- 如果
array
是null
、undefined
或者是空数组,直接返回[]
- 简洁的写法同时检查了数组存在性和长度
例如:
javascript
_.take(null); // => []
_.take([]); // => []
_.take(undefined); // => []
参数处理
javascript
n = guard || n === undefined ? 1 : toInteger(n);
这段代码处理切片数量:
- 如果存在
guard
参数或n
未定义,使用默认值1
- 否则,将
n
转换为整数
其中 guard
参数用于在将 take
作为迭代器传给高阶函数时避免误解额外参数。这确保了即使传入非数字类型,也能得到合理的整数值:
javascript
_.take([1, 2, 3]); // 默认取1个元素: [1]
_.take([1, 2, 3], "2"); // 转换为数字2: [1, 2]
_.take([1, 2, 3], 2.9); // 转换为整数2: [1, 2]
切片操作
javascript
return baseSlice(array, 0, n < 0 ? 0 : n);
核心切片逻辑:
- 从索引
0
开始(数组开头) - 切到索引
n
(不包含) - 如果
n
小于0
,使用0
作为结束索引,返回空数组
例如:
javascript
// n为正数:取前n个
_.take([1, 2, 3, 4], 2); // => [1, 2]
// n为0:返回空数组
_.take([1, 2, 3, 4], 0); // => []
// n为负数:也返回空数组
_.take([1, 2, 3, 4], -2); // => []
// n超过数组长度:返回整个数组
_.take([1, 2, 3], 5); // => [1, 2, 3]
总结
take
函数虽然实现简单,但它体现了几个重要的编程原则:
- 单一职责:专注于一个任务(提取数组开头元素)
- 不可变性:返回新数组而非修改原数组
- 健壮性:处理边界情况和各种输入类型
- 实用性:解决日常编程中的常见需求
这个简洁的函数在数据处理和 UI 展示中非常有用,可以用来创建预览、实现分页、限制结果数量等,是 Lodash 中实用且易于理解的工具函数之一。