Lodash 源码阅读-takeRight
概述
takeRight
函数用于从数组末尾提取指定数量的元素并返回新数组。它与 take
是一对,一个从开头取,一个从末尾取。原数组不会被修改,始终返回一个新数组。
前置学习
依赖函数
- baseSlice:内部切片函数,实际干活的是它
- toInteger:把各种类型的值转成整数
技术知识
- 数组切片:从数组中提取部分元素形成新数组
- 参数默认值:参数未提供时使用默认值
- 索引计算:根据数组长度和要提取的元素数量计算切片范围
- Guard 参数:在高阶函数中防止额外参数误用
- 边界处理:处理各种特殊输入和边界情况
源码实现
javascript
/**
* Creates a slice of `array` with `n` elements taken from the end.
*
* @static
* @memberOf _
* @since 3.0.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
*
* _.takeRight([1, 2, 3]);
* // => [3]
*
* _.takeRight([1, 2, 3], 2);
* // => [2, 3]
*
* _.takeRight([1, 2, 3], 5);
* // => [1, 2, 3]
*
* _.takeRight([1, 2, 3], 0);
* // => []
*/
function takeRight(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = guard || n === undefined ? 1 : toInteger(n);
n = length - n;
return baseSlice(array, n < 0 ? 0 : n, length);
}
实现思路
takeRight
的实现非常直观:
- 先检查数组是否有效(存在且有长度),无效就返回空数组
- 确定要提取的元素数量
n
,默认是 1 - 计算切片的起始位置:
length - n
- 用
baseSlice
从这个位置切到数组末尾 - 如果计算出的位置是负数(取的比数组长度还多),就从 0 开始(返回整个数组)
源码解析
空值和长度检查
javascript
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
这两行代码处理了边界情况:
- 先用
array == null
检查数组是否为null
或undefined
- 如果是,长度就是 0;否则获取数组的实际长度
- 如果长度为 0(空数组或无效输入),直接返回空数组
使用 ==
而不是 ===
让我们可以一次检查 null
和 undefined
两种情况,很方便。
参数处理
javascript
n = guard || n === undefined ? 1 : toInteger(n);
这行代码处理取元素的数量:
- 如果有
guard
参数(比如在_.map
里用takeRight
当迭代器),或者没传n
,就用默认值 1 - 否则用
toInteger
把n
转成整数,确保计算准确
这样可以灵活处理各种输入情况,并提供合理的默认行为。
计算切片范围
javascript
n = length - n;
这行计算实际切片的起始位置:
- 用数组长度减去要提取的元素数量
- 例如:数组
[1, 2, 3]
长度为 3,要取末尾 2 个元素,那么起始位置就是3 - 2 = 1
,即从索引 1 开始(也就是第二个元素)
执行切片
javascript
return baseSlice(array, n < 0 ? 0 : n, length);
最后调用 baseSlice
执行实际切片操作:
- 从计算出的位置
n
开始 - 如果
n
小于 0(说明取的元素比数组长度还多),就从 0 开始,也就是返回整个数组 - 切到数组末尾(
length
) - 返回新的数组切片
例如:对于 [1, 2, 3]
,如果 n
是 5,计算出 n = 3 - 5 = -2
,小于 0,所以从 0 开始切,得到 [1, 2, 3]
。
总结
takeRight
是个简单但很实用的数组处理函数,具有以下特点:
-
方向性操作 - 专注于从数组末尾获取元素,与
take
形成互补 -
灵活性强 - 可以获取任意数量的元素,处理各种边界情况
-
不可变原则 - 不修改原数组,返回新数组,符合函数式编程理念
-
智能边界处理 - 当请求的元素超过数组长度时,返回整个数组而不是报错
这个函数在很多场景下都很有用,比如:获取最近几条记录、保留历史数据中的最新条目、处理数据队列的尾部元素等。在处理需要"从末尾取 N 个元素"这类操作时,takeRight
比手动计算索引和使用 slice
更直观、更不容易出错。