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

相关推荐
LuciferHuang5 小时前
震惊!三万star开源项目竟有致命Bug?
前端·javascript·debug
GISer_Jing5 小时前
前端实习总结——案例与大纲
前端·javascript
天天进步20155 小时前
前端工程化:Webpack从入门到精通
前端·webpack·node.js
姑苏洛言6 小时前
编写产品需求文档:黄历日历小程序
前端·javascript·后端
知识分享小能手7 小时前
Vue3 学习教程,从入门到精通,使用 VSCode 开发 Vue3 的详细指南(3)
前端·javascript·vue.js·学习·前端框架·vue·vue3
姑苏洛言7 小时前
搭建一款结合传统黄历功能的日历小程序
前端·javascript·后端
hackchen7 小时前
Go与JS无缝协作:Goja引擎实战之错误处理最佳实践
开发语言·javascript·golang
你的人类朋友8 小时前
🤔什么时候用BFF架构?
前端·javascript·后端
知识分享小能手8 小时前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3