Lodash源码阅读-baseFill

Lodash 源码阅读-baseFill

概述

baseFill 是 Lodash 内部用来实现 fill 方法的核心函数,它能够用指定值填充数组中的元素,支持指定起始和结束位置。这个函数处理了各种边界情况,并且保证了填充操作的准确性。

前置学习

依赖函数

  • toInteger:将值转换为整数,处理起始位置和结束位置参数
  • toLength:将值转换为有效的数组长度,确保结束位置在有效范围内

技术知识

  • 数组操作:数组元素的赋值和修改
  • 循环控制:使用 while 循环进行数组元素填充
  • 参数处理:处理负数索引、起始位置大于结束位置等边界情况

源码实现

javascript 复制代码
function baseFill(array, value, start, end) {
  var length = array.length;

  start = toInteger(start);
  if (start < 0) {
    start = -start > length ? 0 : length + start;
  }
  end = end === undefined || end > length ? length : toInteger(end);
  if (end < 0) {
    end += length;
  }
  end = start > end ? 0 : toLength(end);
  while (start < end) {
    array[start++] = value;
  }
  return array;
}

实现思路

baseFill 的实现逻辑非常直观但很完善:

  1. 首先获取数组的长度
  2. 处理起始位置参数 start
    • 转换为整数
    • 如果为负数,将其转换为相对于数组末尾的位置
    • 如果转换后仍小于 0,则设为 0
  3. 处理结束位置参数 end
    • 如果未定义或大于数组长度,则设为数组长度
    • 否则转换为整数
    • 如果为负数,将其转换为相对于数组末尾的位置
  4. 确保结束位置有效:
    • 如果起始位置大于结束位置,则结束位置设为 0
    • 否则使用 toLength 确保结束位置在有效范围内
  5. 使用循环将指定值填充到数组的指定位置
  6. 返回修改后的数组

源码解析

初始化和参数处理

javascript 复制代码
var length = array.length;

start = toInteger(start);
if (start < 0) {
  start = -start > length ? 0 : length + start;
}

这部分代码首先获取数组长度,然后处理起始位置 start

  • 使用 toInteger 将其转换为整数
  • 如果是负数,则计算相对于数组末尾的位置
  • 如果负数的绝对值大于数组长度,就设为 0

例如:

javascript 复制代码
// 数组长度为5
start = -2 => 5 + (-2) = 3  // 表示从倒数第二个元素开始
start = -10 => 0           // 因为|-10| > 5,所以设为0

结束位置处理

javascript 复制代码
end = end === undefined || end > length ? length : toInteger(end);
if (end < 0) {
  end += length;
}
end = start > end ? 0 : toLength(end);

这部分代码处理结束位置 end

  • 如果未定义或大于数组长度,设为数组长度
  • 否则转换为整数
  • 如果是负数,计算相对于数组末尾的位置
  • 最后,如果起始位置大于结束位置,则结束位置设为 0;否则使用 toLength 确保结束位置是一个有效的数组长度值

例如:

javascript 复制代码
// 数组长度为5,start为1
end = undefined => 5      // 未定义,设为数组长度
end = -2 => 5 + (-2) = 3  // 表示倒数第二个元素的位置
end = 10 => 5             // 超出数组长度,设为数组长度

填充操作

javascript 复制代码
while (start < end) {
  array[start++] = value;
}
return array;

这是函数的核心填充逻辑:

  • 使用 while 循环从起始位置到结束位置(不包括结束位置)
  • 在每个位置设置指定的值
  • 使用 start++ 同时赋值和递增索引
  • 最后返回修改后的数组

总结

baseFill 函数看似简单,但它展示了几个重要的编程原则:

  1. 健壮性:通过仔细处理边界情况(负索引、超出范围的值等)确保函数在各种输入下都能正常工作

  2. 参数规范化 :使用 toIntegertoLength 将输入标准化,增强函数的适应性

  3. 副作用明确:函数直接修改并返回原数组,使得副作用明确且可预测

baseFill 是一个很好的例子,展示了如何处理数组边界和索引转换,这在很多数组操作中都是常见且重要的技术。

相关推荐
扯蛋4381 小时前
LangChain的学习之路( 一 )
前端·langchain·mcp
Mr.Jessy1 小时前
Web APIs学习第一天:获取 DOM 对象
开发语言·前端·javascript·学习·html
午安~婉1 小时前
javaScript八股问题
开发语言·javascript·原型模式
西西学代码2 小时前
Flutter---个人信息(5)---持久化存储
java·javascript·flutter
芝麻开门-新起点2 小时前
flutter 生命周期管理:从 Widget 到 State 的完整解析
开发语言·javascript·ecmascript
ConardLi3 小时前
Easy Dataset 已经突破 11.5K Star,这次又带来多项功能更新!
前端·javascript·后端
冴羽3 小时前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
rising start3 小时前
四、CSS选择器(续)和三大特性
前端·css
一 乐3 小时前
高校后勤报修系统|物业管理|基于SprinBoot+vue的高校后勤报修系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·毕设
爱喝水的小周3 小时前
《UniApp 页面配置文件pages.json》
前端·uni-app·json