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

相关推荐
wh_xia_jun3 分钟前
在 Spring Boot 中使用 JSP
java·前端·spring boot
二十雨辰22 分钟前
[HTML5]快速掌握canvas
前端·html
tingkeiii1 小时前
【react+antd+vite】优雅的引入svg和阿里巴巴图标
前端·react.js·前端框架
清幽竹客1 小时前
vue-18(使用 Vuex 插件实现高级功能)
前端·vue.js·前端框架·vue
粥里有勺糖1 小时前
用Trae做了个公众号小工具
前端·ai编程·trae
棉花糖超人2 小时前
【从0-1的HTML】第2篇:HTML标签
前端·html
exploration-earth2 小时前
本地优先的状态管理与工具选型策略
开发语言·前端·javascript
OpenTiny社区3 小时前
开源之夏报名倒计时3天!还有9个前端任务有余位,快来申请吧~
前端·github
ak啊3 小时前
WebGL魔法:从立方体到逼真阴影的奇妙之旅
前端·webgl
hang_bro3 小时前
使用js方法实现阻止按钮的默认点击事件&触发默认事件
前端·react.js·html