Lodash源码阅读-basePullAt

Lodash 源码阅读-basePullAt

概述

basePullAt 是 Lodash 内部的工具函数,用于从数组中移除指定索引位置的元素。它是 _.pullAt 方法的底层实现,支持同时移除多个索引位置的元素,并且会修改原数组。

前置学习

依赖函数

  • isIndex: 判断一个值是否为有效的数组索引
  • baseUnset: 移除对象属性的内部方法(用于非数字索引)
  • splice: JavaScript 原生数组方法,用于删除数组元素

技术知识

  • 数组修改操作: 原地修改数组的方法
  • 函数绑定 : 使用 call 方法调用函数并绑定 this
  • 稀疏数组: JavaScript 中的非连续索引数组
  • 索引处理: 数组索引与对象属性的区别

源码实现

js 复制代码
function basePullAt(array, indexes) {
  var length = array ? indexes.length : 0,
    lastIndex = length - 1;

  while (length--) {
    var index = indexes[length];
    if (length == lastIndex || index !== previous) {
      var previous = index;
      if (isIndex(index)) {
        splice.call(array, index, 1);
      } else {
        baseUnset(array, index);
      }
    }
  }
  return array;
}

实现思路

basePullAt 函数的设计思路非常巧妙:

  1. 从后向前遍历索引数组,这样在删除元素时不会影响后续元素的索引位置
  2. 使用 isIndex 判断索引是否为有效的数组索引
  3. 对于有效的数组索引,使用原生的 splice 方法删除元素
  4. 对于非数字索引(对象属性),使用 baseUnset 方法删除
  5. 跳过重复的索引,避免多次尝试删除同一位置的元素
  6. 返回修改后的原数组

这种实现方式保证了高效的数组元素删除,并且处理了各种边界情况。

源码解析

让我们逐步解析 basePullAt 函数的实现:

js 复制代码
function basePullAt(array, indexes) {
  var length = array ? indexes.length : 0,
      lastIndex = length - 1;

首先,函数检查 array 是否存在,如果存在,则获取 indexes 数组的长度;如果不存在,则将长度设为 0。同时计算出最后一个索引的位置。

js 复制代码
while (length--) {
  var index = indexes[length];

函数使用了从后向前的遍历方式(length--),这样当删除前面的元素时,不会影响后面元素的索引位置。在每次循环中,获取当前要处理的索引值。

js 复制代码
if (length == lastIndex || index !== previous) {
  var previous = index;

这段代码检查当前索引是否是最后一个索引或者与前一个处理的索引不同。这是为了避免重复处理相同的索引。如果 indexes 数组中包含重复的索引,只有第一次遇到时才会执行删除操作。

js 复制代码
if (isIndex(index)) {
  splice.call(array, index, 1);
} else {
  baseUnset(array, index);
}

根据索引类型选择不同的删除方法:

  • 如果是有效的数组索引(通过 isIndex 函数判断),使用 splice.call(array, index, 1) 方法从数组中删除该位置的元素。
  • 如果不是有效的数组索引(可能是字符串属性名),使用 baseUnset(array, index) 方法删除该属性。
js 复制代码
}
}
return array;

最后,函数返回修改后的原数组。

应用示例

js 复制代码
var array = ["a", "b", "c", "d"];
basePullAt(array, [1, 3]);
// 移除索引 1 和 3 的元素
// array 变成 ['a', 'c']

var obj = { 0: "a", 1: "b", foo: "bar" };
basePullAt(obj, [1, "foo"]);
// 移除索引 1 和属性 'foo'
// obj 变成 { '0': 'a' }

总结

basePullAt 函数是一个精巧的数组元素删除工具,它具有以下几个设计亮点:

  1. 逆序遍历: 从后向前删除元素,避免索引位置变化导致的问题。
  2. 类型判断: 区分处理数组索引和对象属性,使用不同的删除方法。
  3. 去重处理: 避免对重复索引进行多次操作,提高效率。
  4. 原地修改: 直接修改原数组,不创建新数组,节省内存。

这个函数体现了 Lodash 在处理数组操作时的细致考量,包括性能优化和边界情况的处理。理解这种实现方式对于我们设计自己的数组操作函数也有很大的启发。

相关推荐
我是ed.8 分钟前
cocos Js 使用 webview 通过 postMessage 进行通信
开发语言·javascript·ecmascript
程序视点8 分钟前
Wise Duplicate Finder 重复文件查找工具 - 永久免费专业版文件去重工具
前端·windows
一点一木1 小时前
🚀 2025 年 07 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github
脑袋大大的1 小时前
uni-app x开发避坑指南:拯救被卡顿的UI线程!
开发语言·前端·javascript·vue.js·ui·uni-app·uts
ayas123191 小时前
CSS学习
前端·css·学习
人生在勤,不索何获-白大侠2 小时前
day25——HTML & CSS 前端开发
前端·css·html
Running_C2 小时前
Content-Type的几种类型
前端·面试
前端Hardy2 小时前
10 分钟搞定婚礼小程序?我用 DeepSeek 把同学的作业卷成了范本!
前端·javascript·微信小程序
Tminihu2 小时前
前端大文件上传的时候,采用切片上传的方式,如果断网了,应该如何处理
前端·javascript
颜酱2 小时前
理解vue3中的compiler-core
前端·javascript·vue.js