Lodash源码阅读-takeRight

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 的实现非常直观:

  1. 先检查数组是否有效(存在且有长度),无效就返回空数组
  2. 确定要提取的元素数量 n,默认是 1
  3. 计算切片的起始位置:length - n
  4. baseSlice 从这个位置切到数组末尾
  5. 如果计算出的位置是负数(取的比数组长度还多),就从 0 开始(返回整个数组)

源码解析

空值和长度检查

javascript 复制代码
var length = array == null ? 0 : array.length;
if (!length) {
  return [];
}

这两行代码处理了边界情况:

  • 先用 array == null 检查数组是否为 nullundefined
  • 如果是,长度就是 0;否则获取数组的实际长度
  • 如果长度为 0(空数组或无效输入),直接返回空数组

使用 == 而不是 === 让我们可以一次检查 nullundefined 两种情况,很方便。

参数处理

javascript 复制代码
n = guard || n === undefined ? 1 : toInteger(n);

这行代码处理取元素的数量:

  • 如果有 guard 参数(比如在 _.map 里用 takeRight 当迭代器),或者没传 n,就用默认值 1
  • 否则用 toIntegern 转成整数,确保计算准确

这样可以灵活处理各种输入情况,并提供合理的默认行为。

计算切片范围

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 是个简单但很实用的数组处理函数,具有以下特点:

  1. 方向性操作 - 专注于从数组末尾获取元素,与 take 形成互补

  2. 灵活性强 - 可以获取任意数量的元素,处理各种边界情况

  3. 不可变原则 - 不修改原数组,返回新数组,符合函数式编程理念

  4. 智能边界处理 - 当请求的元素超过数组长度时,返回整个数组而不是报错

这个函数在很多场景下都很有用,比如:获取最近几条记录、保留历史数据中的最新条目、处理数据队列的尾部元素等。在处理需要"从末尾取 N 个元素"这类操作时,takeRight 比手动计算索引和使用 slice 更直观、更不容易出错。

相关推荐
海晨忆4 分钟前
【Vue】v-if和v-show的区别
前端·javascript·vue.js·v-show·v-if
JiangJiang29 分钟前
🚀 Vue人看React useRef:它不只是替代 ref
javascript·react.js·面试
1024小神33 分钟前
在GitHub action中使用添加项目中配置文件的值为环境变量
前端·javascript
龙骑utr38 分钟前
qiankun微应用动态设置静态资源访问路径
javascript
Jasmin Tin Wei38 分钟前
css易混淆的知识点
开发语言·javascript·ecmascript
齐尹秦42 分钟前
CSS 列表样式学习笔记
前端
wsz77771 小时前
js封装系列(一)
javascript
Mnxj1 小时前
渐变边框设计
前端
用户7678797737321 小时前
由Umi升级到Next方案
前端·next.js
快乐的小前端1 小时前
TypeScript基础一
前端