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 更直观、更不容易出错。

相关推荐
百万蹄蹄向前冲9 分钟前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5811 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路1 小时前
GeoTools 读取影像元数据
前端
ssshooter1 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友1 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry2 小时前
Jetpack Compose 中的状态
前端
dae bal3 小时前
关于RSA和AES加密
前端·vue.js
柳杉3 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog3 小时前
低端设备加载webp ANR
前端·算法
LKAI.4 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi