Lodash源码阅读-arrayMap

Lodash 源码阅读-arrayMap

概述

arrayMap 是 Lodash 中的一个内部工具函数,专门用于对数组进行映射操作。它是 _.map 函数在处理数组类型时的底层实现,提供了高效的数组元素转换功能。

前置学习

  • Array 构造函数:了解 JavaScript 中如何预分配指定长度的数组
  • 数组遍历 :了解 JavaScript 中的循环遍历方法,特别是 while 循环
  • 函数回调:理解如何将函数作为参数传递并在循环中调用

源码实现

js 复制代码
function arrayMap(array, iteratee) {
  var index = -1,
    length = array == null ? 0 : array.length,
    result = Array(length);

  while (++index < length) {
    result[index] = iteratee(array[index], index, array);
  }
  return result;
}

实现思路

arrayMap 函数的实现非常直接明了:它接收一个数组和一个迭代函数作为参数,然后遍历数组中的每个元素,对每个元素应用迭代函数,并将结果存储在一个新数组中。最后返回这个新数组。

这个函数是 _.map 的专用版本,专门针对数组类型进行了优化,不支持 Lodash 中常见的迭代器简写形式(如字符串路径、对象等)。

源码解析

1. 参数处理和初始化

js 复制代码
var index = -1,
  length = array == null ? 0 : array.length,
  result = Array(length);

这部分代码完成了三个初始化操作:

  1. 初始化索引 :将 index 设置为 -1,为后续的 ++index 操作做准备
  2. 获取数组长度 :检查 array 是否为 nullundefined,如果是则长度为 0,否则获取其 length 属性
  3. 创建结果数组 :使用 Array(length) 预分配一个与输入数组相同长度的新数组

这里使用 array == null 而不是 array === null || array === undefined 是一种简洁的写法,因为在 JavaScript 中,null == undefinedtrue

预分配结果数组的长度是一种优化手段,避免了在循环过程中动态扩展数组带来的性能开销。

2. 数组遍历和映射

js 复制代码
while (++index < length) {
  result[index] = iteratee(array[index], index, array);
}

这部分代码使用 while 循环遍历数组的每个元素:

  1. ++index < length 在每次循环开始时递增索引,并检查是否已遍历完所有元素
  2. 对于每个元素,调用 iteratee 函数,传入三个参数:
    • 当前元素值:array[index]
    • 当前索引:index
    • 原始数组:array
  3. iteratee 函数的返回值存储在结果数组的相应位置

这种实现方式保持了与 JavaScript 原生 Array.prototype.map() 方法相同的参数顺序和行为,使得函数易于理解和使用。

3. 返回结果

js 复制代码
return result;

最后,函数返回包含所有映射结果的新数组。

应用场景

在 Lodash 中的作用

arrayMap 在 Lodash 中主要用于以下场景:

  1. 作为 _.map 函数的数组处理实现 :当 _.map 检测到输入集合是数组时,会调用 arrayMap 进行处理

    js 复制代码
    // 在 _.map 函数中的使用
    function map(collection, iteratee) {
      var func = isArray(collection) ? arrayMap : baseMap;
      return func(collection, getIteratee(iteratee, 3));
    }
  2. 在其他 Lodash 函数中用于数组转换 :如 baseToPairs 等函数内部使用 arrayMap 进行数组转换

    js 复制代码
    // 在 baseToPairs 函数中的使用
    function baseToPairs(object, props) {
      return arrayMap(props, function (key) {
        return [key, object[key]];
      });
    }

在前端开发中的应用

虽然我们很少直接使用 arrayMap,但其实现思想在前端开发中有广泛应用:

  1. 数据转换:将一组数据转换为另一种格式,如将用户数据转换为视图模型

    js 复制代码
    const userViewModels = arrayMap(users, (user) => ({
      displayName: `${user.firstName} ${user.lastName}`,
      avatarUrl: user.profilePicture || "default.png",
      isActive: user.status === "active",
    }));
  2. DOM 操作:将数据数组转换为 DOM 元素数组

    js 复制代码
    const listItems = arrayMap(items, (item) => {
      const li = document.createElement("li");
      li.textContent = item.name;
      return li;
    });
  3. 计算派生值:基于原始数据计算新的数据集

    js 复制代码
    const prices = arrayMap(products, (product) => product.price);
    const averagePrice =
      prices.reduce((sum, price) => sum + price, 0) / prices.length;

总结

arrayMap 函数是 Lodash 中一个简洁而高效的内部工具函数,它专门用于处理数组的映射操作。通过预分配结果数组和简单的循环实现,它提供了良好的性能和可靠的行为。

从设计角度看,arrayMap 函数体现了以下几点优秀的编程实践:

  1. 单一职责:函数只专注于数组映射这一任务,不处理其他类型的集合
  2. 性能优化:通过预分配结果数组长度,避免了动态扩展数组的开销
  3. 健壮性 :正确处理了 nullundefined 输入的情况
  4. 一致性 :保持了与 JavaScript 原生 Array.prototype.map() 相同的参数顺序和行为

这种专门化的设计使得 Lodash 能够在处理不同类型的集合时选择最优的实现方式,既保证了功能的完整性,又兼顾了性能的优化。

相关推荐
哆啦A梦158817 分钟前
商城后台管理系统 03 登录布局
javascript·vue.js·elementui
曼巴UE542 分钟前
UE FString, FName ,FText 三者转换,再次学习,官方文档理解
服务器·前端·javascript
selt7911 小时前
Redisson之RedissonLock源码完全解析
android·java·javascript
行走的陀螺仪1 小时前
高级前端 Input 公共组件设计方案(Vue3 + TypeScript)
前端·javascript·typescript·vue·组件设计方案
一颗不甘坠落的流星2 小时前
【Antd】基于 Upload 组件,导入Json文件并转换为Json数据
前端·javascript·json
LYFlied2 小时前
Vue2 与 Vue3 虚拟DOM更新原理深度解析
前端·javascript·vue.js·虚拟dom
Lucky_Turtle2 小时前
【Node】npm install报错npm error Cannot read properties of null (reading ‘matches‘)
前端·npm·node.js
小飞侠在吗2 小时前
vue shallowRef 与 shallowReacitive
前端·javascript·vue.js
惜分飞3 小时前
sql server 事务日志备份异常恢复案例---惜分飞
前端·数据库·php