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

相关推荐
QTX187302 分钟前
使用 Axios 进行 API 请求与接口封装
javascript·vue.js·node.js
9ilk12 分钟前
【前端基础】--- HTML
前端·html
Lafar14 分钟前
Dart单线程怎么保证UI运行流畅
前端·面试
不和乔治玩的佩奇20 分钟前
【 设计模式】常见前端设计模式
前端
bloxed26 分钟前
vue+vite 减缓首屏加载压力和性能优化
前端·vue.js·性能优化
打野赵怀真38 分钟前
React Hooks 的优势和使用场景
前端·javascript
HaushoLin42 分钟前
ERR_PNPM_DLX_NO_BIN No binaries found in tailwindcss
前端·vue.js·css3·html5
Lafar43 分钟前
Widget 树和 Element 树和RenderObject树是一一 对应的吗
前端
似水流年QC43 分钟前
什么是Lodash
javascript·lodash
小桥风满袖44 分钟前
炸裂,前端神级动效库合集
前端·css