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

相关推荐
q***498610 分钟前
MySQL数据的增删改查(一)
android·javascript·mysql
我有一个object11 分钟前
uniapp上传文件报错:targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!
前端·javascript·vue.js·uniapp
北极糊的狐15 分钟前
关于jQuery 事件绑定,记录常用事件类型及核心注意事项
前端·javascript·jquery
星空的资源小屋17 分钟前
极速精准!XSearch本地文件搜索神器
javascript·人工智能·django·电脑
_Kayo_21 分钟前
vue3 computed 练习笔记
前端·vue.js·笔记
CodeSheep25 分钟前
VS 2026 正式发布,王炸!
前端·后端·程序员
无奈何杨25 分钟前
CoolGuard事件查询增加策略和规则筛选,条件结果展示
前端·后端
梦里不知身是客1128 分钟前
正则表达式常见的介绍
前端·javascript·正则表达式
初学小白...1 小时前
HTML知识点
前端·javascript·html
鹏多多1 小时前
flutter睡眠与冥想数据可视化神器:sleep_stage_chart插件全解析
android·前端·flutter