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

相关推荐
树叶会结冰10 分钟前
HTML语义化:当网页会说话
前端·html
冰万森16 分钟前
解决 React 项目初始化(npx create-react-app)速度慢的 7 个实用方案
前端·react.js·前端框架
牧羊人_myr29 分钟前
Ajax 技术详解
前端
浩男孩38 分钟前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端
蓝银草同学42 分钟前
阿里 Iconfont 项目丢失?手把手教你将已引用的 SVG 图标下载到本地
前端·icon
布列瑟农的星空1 小时前
重学React —— React事件机制 vs 浏览器事件机制
前端
一小池勺1 小时前
CommonJS
前端·面试
孙牛牛1 小时前
实战分享:一招解决嵌套依赖版本失控问题,以 undici 为例
前端
用户52709648744901 小时前
Git 最佳实践
前端