Lodash源码阅读-last

功能概述

last 函数是 Lodash 中的一个实用数组方法,主要用于获取数组的最后一个元素。与 head 函数获取第一个元素相对应,last 函数获取数组的末尾元素。这个函数同样处理了各种边缘情况,如空数组、null 或 undefined 输入等。

源码实现

js 复制代码
function last(array) {
  var length = array == null ? 0 : array.length;
  return length ? array[length - 1] : undefined;
}

实现原理解析

原理概述

last 函数的实现原理清晰明了:首先获取数组的长度,如果数组有效且长度大于 0,则返回数组的最后一个元素(索引为 length - 1 的元素);否则返回 undefined。这种实现方式安全地处理了各种边缘情况,包括 null、undefined 和空数组输入,同时保持了代码的简洁性和可读性。

整个过程可以概括为:

  1. 获取输入数组的长度,处理 null 和 undefined 的情况
  2. 检查长度是否为真值(大于 0)
  3. 如果长度大于 0,返回最后一个元素;否则返回 undefined

代码解析

1. 获取数组长度

js 复制代码
var length = array == null ? 0 : array.length;

这行代码首先处理了数组可能为 null 或 undefined 的情况:

  • array == null 是一个简洁的检查,它同时匹配 array === nullarray === undefined
  • 如果 array 是 null 或 undefined,则将 length 设置为 0
  • 否则,获取 array.length 作为数组长度

示例:

js 复制代码
// 当传入正常数组时
var arr = [1, 2, 3];
var length = arr == null ? 0 : arr.length; // length = 3

// 当传入空数组时
var arr = [];
var length = arr == null ? 0 : arr.length; // length = 0

// 当传入 null 时
var arr = null;
var length = arr == null ? 0 : arr.length; // length = 0

// 当传入 undefined 时
var arr = undefined;
var length = arr == null ? 0 : arr.length; // length = 0

// 当传入非数组对象时
var arr = { a: 1 };
var length = arr == null ? 0 : arr.length; // length = undefined

2. 条件返回最后一个元素

js 复制代码
return length ? array[length - 1] : undefined;

这行代码使用三元操作符根据 length 的值决定返回什么:

  • 如果 length 为真值(大于 0),返回 array[length - 1](最后一个元素)
  • 否则返回 undefined

示例:

js 复制代码
// 有效非空数组
last([1, 2, 3]); // length = 3,返回 array[2],即 3

// 只有一个元素的数组
last([42]); // length = 1,返回 array[0],即 42

// 空数组
last([]); // length = 0,返回 undefined

// null 或 undefined
last(null); // length = 0,返回 undefined
last(undefined); // length = 0,返回 undefined

// 非数组对象
last({}); // length = undefined,在布尔上下文中为 false,返回 undefined

使用示例

js 复制代码
// 获取普通数组的最后一个元素
_.last([1, 2, 3]);
// => 3

// 处理只有一个元素的数组
_.last([42]);
// => 42

// 处理空数组
_.last([]);
// => undefined

// 处理 null 或 undefined
_.last(null);
// => undefined
_.last(undefined);
// => undefined

// 处理字符串(类数组对象)
_.last("abc");
// => 'c'

// 处理类数组对象
_.last({ 0: "a", 1: "b", length: 2 });
// => 'b'

与其他方法的比较

  1. last vs Array.prototype.slice:与使用 slice(-1)[0] 相比,last 函数更简洁且处理了边缘情况。
js 复制代码
// 使用 slice 获取最后一个元素
[1, 2, 3].slice(-1)[0]; // 3

// 但 slice 在处理 null 或 undefined 时会出错
// null.slice(-1)[0]; // TypeError: Cannot read property 'slice' of null

// last 函数安全处理边缘情况
_.last(null); // undefined
  1. last vs Array.prototype.pop:与 pop 不同,last 不会修改原数组。
js 复制代码
const arr = [1, 2, 3];

// pop 会移除并返回最后一个元素
arr.pop(); // 返回 3
console.log(arr); // [1, 2]

// last 不会修改原数组
const newArr = [1, 2, 3];
_.last(newArr); // 返回 3
console.log(newArr); // 仍然是 [1, 2, 3]
  1. last vs 直接索引访问:与直接使用 array[array.length - 1] 相比,last 函数处理了边缘情况。
js 复制代码
// 直接索引访问可能导致错误
// null[null.length - 1]; // TypeError

// 空数组直接访问会返回 undefined,但代码不够优雅
[][].length - 1]; // undefined,但写法复杂且容易出错

// last 函数提供了更安全、更简洁的方式
_.last(null); // undefined
_.last([]); // undefined

注意事项

  1. 返回 undefined 的情况:last 函数在以下情况会返回 undefined:

    • 输入是空数组 []
    • 输入是 null 或 undefined
    • 输入是没有 length 属性的对象
    • 输入是 length 为 0 的类数组对象
  2. 类数组对象:last 函数可以处理类数组对象,但需要注意索引和 length 属性的一致性。

js 复制代码
// 字符串是类数组对象
_.last("hello"); // 'o'

// 自定义类数组对象
const arrayLike = { 0: "a", 1: "b", length: 2 };
_.last(arrayLike); // 'b'

// 但如果 length 属性与实际索引不匹配,可能得到意外结果
const mismatchedArrayLike = { 0: "a", 1: "b", length: 3 };
_.last(mismatchedArrayLike); // undefined,因为索引 2 处没有值

总结

Lodash 的 last 函数是一个简单但实用的工具,它通过简洁的代码安全地获取数组的最后一个元素。虽然功能看似基础,但它处理了各种边缘情况,使代码更加健壮和可靠。

相关推荐
小兔崽子去哪了12 分钟前
微信小程序入门
前端·vue.js·微信小程序
独立开阀者_FwtCoder15 分钟前
# 白嫖千刀亲测可行——200刀拿下 Cursor、V0、Bolt和Perplexity 等等 1 年会员
前端·javascript·面试
不和乔治玩的佩奇22 分钟前
【 React 】useState (温故知新)
前端
那小孩儿22 分钟前
?? 、 || 、&&=、||=、??=这些运算符你用对了吗?
前端·javascript
七月十二25 分钟前
[微信小程序]对接sse接口
前端·微信小程序
小七_雪球27 分钟前
Permission denied"如何解决?详解GitHub SSH密钥认证流程
前端·github
野原猫之助28 分钟前
tailwind css在antd组件中使用不生效
前端
菜鸟码农_Shi30 分钟前
Node.js 如何实现 GitHub 登录(OAuth 2.0)
javascript·node.js
没资格抱怨35 分钟前
如何在vue3项目中使用 AbortController取消axios请求
前端·javascript·vue.js
掘金酱39 分钟前
😊 酱酱宝的推荐:做任务赢积分“拿”华为MatePad Air、雷蛇机械键盘、 热门APP会员卡...
前端·后端·trae