功能概述
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 和空数组输入,同时保持了代码的简洁性和可读性。
整个过程可以概括为:
- 获取输入数组的长度,处理 null 和 undefined 的情况
- 检查长度是否为真值(大于 0)
- 如果长度大于 0,返回最后一个元素;否则返回 undefined
代码解析
1. 获取数组长度
js
var length = array == null ? 0 : array.length;
这行代码首先处理了数组可能为 null 或 undefined 的情况:
array == null
是一个简洁的检查,它同时匹配array === null
和array === 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'
与其他方法的比较
- 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
- 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]
- last vs 直接索引访问:与直接使用 array[array.length - 1] 相比,last 函数处理了边缘情况。
js
// 直接索引访问可能导致错误
// null[null.length - 1]; // TypeError
// 空数组直接访问会返回 undefined,但代码不够优雅
[][].length - 1]; // undefined,但写法复杂且容易出错
// last 函数提供了更安全、更简洁的方式
_.last(null); // undefined
_.last([]); // undefined
注意事项
-
返回 undefined 的情况:last 函数在以下情况会返回 undefined:
- 输入是空数组
[]
- 输入是 null 或 undefined
- 输入是没有 length 属性的对象
- 输入是 length 为 0 的类数组对象
- 输入是空数组
-
类数组对象: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 函数是一个简单但实用的工具,它通过简洁的代码安全地获取数组的最后一个元素。虽然功能看似基础,但它处理了各种边缘情况,使代码更加健壮和可靠。