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

相关推荐
emojiwoo1 小时前
【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)
前端·react.js·前端框架
张人玉1 小时前
XML 序列化与操作详解笔记
xml·前端·笔记
杨荧2 小时前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
YeeWang2 小时前
🎉 Eficy 让你的 Cherry Studio 直接生成可预览的 React 页面
前端·javascript
gnip2 小时前
Jenkins部署前端项目实战方案
前端·javascript·架构
Orange3015112 小时前
《深入源码理解webpack构建流程》
前端·javascript·webpack·typescript·node.js·es6
lovepenny3 小时前
Failed to resolve entry for package "js-demo-tools". The package may have ......
前端·npm
超凌3 小时前
threejs 创建了10w条THREE.Line,销毁数据,等待了10秒
前端
车厘小团子3 小时前
🎨 前端多主题最佳实践:用 Less Map + generate-css 打造自动化主题系统
前端·架构·less
芒果1253 小时前
SVG图片通过img引入修改颜色
前端