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

相关推荐
爱分享的程序员25 分钟前
全栈架构设计图
前端
KenXu39 分钟前
YYEVA WebGPU 渲染实现技术解析
前端·webgl
~卷心菜~43 分钟前
CSS基础-即学即用 -- 笔记1
前端·css·笔记
我最厉害。,。1 小时前
CSRF 请求伪造&Referer 同源&置空&配合 XSS&Token 值校验&复用删除
前端·xss·csrf
vvilkim1 小时前
深入解析React.lazy与Suspense:现代React应用的性能优化利器
前端·react.js·前端框架
野猪亨利2581 小时前
【JS 小白也能懂】回调函数:让代码学会「听话办事」的魔法
前端
dengzy3211 小时前
js 观察者模式和发布订阅模式详解
javascript
五号厂房1 小时前
前端接口编写的最佳实践总结:设计、实现、维护全流程
前端
Cutey9161 小时前
Vue 实现多语言国际化的完整指南
前端·javascript·面试
广龙宇1 小时前
【Web API系列】Web Shared Storage API 深度解析:WindowSharedStorage 接口实战指南
前端