前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库fill 方法负数 start end 参数
JSJavaScript数组与集合

Array.fill 的负数 start、end 怎样换算,为什么最后一项没有被填?

把负数先换成实际位置,再看左闭右开区间,比凭“倒数第几项”直接猜结果更可靠。

前端进阶之旅 · 一题精讲更新于 2026.09.06
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

把参数转成实际区间

  1. 换算位置负数相对当前数组长度计算
  2. 确定范围使用包含 start、不包含 end 的区间
  3. 执行写入将同一个值赋给范围内每个索引

fill 是写入操作,不能把它当作 slice 那样只读取并返回片段;共享数组的其他持有者会看到修改。

核心回答

先记住这个答案

fill(value, start, end) 修改原数组中起点包含、终点不包含的索引范围。负数位置按 length 加该值换算,再按合法范围裁剪;省略 start 从零开始,省略 end 到长度结束。长度五时 start 为 -3 对应索引二,end 为 -1 对应索引四,因此只填二、三,不包含最后的四。如果终点不大于起点,就不填任何位置。fill 不扩展数组长度,并把同一个 value 放到每个位置;value 是对象时不会为每格创建独立对象。

  • 负索引先加长度再裁剪到边界
  • end 指向的索引不参与填充
  • 返回原数组且每格共享传入的对象值

明确最后一个参数是终点而非数量

下面数组长度五,负三和负一分别换算成二和四,所以两个中间位置被替换。end 不是填多少项,也不是包含式终点;如果想填到最后,应省略 end 或传数组长度。

为了便于检查,示例同时比较返回值身份和原数组内容。只看返回的打印结果容易误以为得到了新数组,实际调用方和其他共享引用看到的是同一份修改后的容器。

负索引换算与原地修改JavaScript
const values = ['A', 'B', 'C', 'D', 'E'];
const returned = values.fill('X', -3, -1);
console.log(JSON.stringify(values));
console.log(returned === values);
console.log(JSON.stringify([1, 2, 3].fill(9, -99, 1)));
console.log(JSON.stringify([1, 2, 3].fill(9, 2, 1)));
查看输出与解释
["A","B","X","X","E"]
true
[9,2,3]
[1,2,3]

过小的负起点被裁剪到零;终点在起点之前时区间为空,数组保持不变。所有例子都在既有长度范围内赋值,不会因越界参数自动增加元素数量。

填充对象时确认是否需要独立实例

用 Array(3).fill({ selected: false }) 创建三行状态时,三格引用同一对象,修改一格的属性会让其他格看到变化。fill 接收的是一个已经求值的 value,而不是每格调用一次的工厂。

需要独立对象时可以用 Array.from 的映射函数逐项创建,或者在已填充的数组上 map 返回新对象。若数据来自只读状态,先决定容器和元素哪一层需要复制,再执行局部填充。

区间为空与数组为空都不会生成新容量

空数组的长度是零,直接 [].fill(0) 仍为空。要创建固定长度内容,应先建立对应长度或使用生成方式,不能指望 fill 根据起止参数自行扩容。

fill 可以给稀疏数组的缺失索引写入真实属性,但它不是任意数据修复器。只读属性、冻结对象或代理拦截可能导致失败,业务层仍应确认目标是允许修改的容器。

回答前,多想一步

容易答错的地方

把 end 为 -1 理解成包含最后一项
负一换算后指向最后索引,但终点本来就不包含,所以最后一项不会写入。应先做索引换算再应用区间规则,避免把自然语言“到最后”与 API 的边界契约混在一起。
用 fill 创建多份独立对象
传给 fill 的对象只创建了一次,每次写入都是同一个引用。若每格需要独立状态,应使用逐项工厂,并通过对象身份和单格修改测试确认没有意外共享。
试着用自己的话回答

面试官还会怎么问?

start 超过数组长度会扩展数组吗?

不会,归一化后的范围没有可填位置,长度保持不变。fill 的职责是修改既有长度范围内的元素,若需求是追加内容,应选择追加或重新构造数组的操作。

fill 会保留空位吗?

被覆盖范围内的缺失索引会写成真实属性,范围外的空位保持原状。因此填充后可能只有一部分变成密集结构,后续 map 是否执行仍应按具体索引存在性判断。

给响应式状态调用 fill 有什么注意点?

首先它修改原容器,是否触发更新取决于所用状态系统的契约;其次对象 value 仍然共享引用。应同时验证框架更新机制和数据身份,不能只因为最终打印值正确就忽略状态传播问题。

从一道题,走向一组知识

把知识连起来

数组与集合

数组 at(-1) 与 arr[-1] 有什么区别,越界和旧环境怎么办?

对照读取单个负索引时的换算与越界行为。

数组与集合

稀疏数组空位与 undefined 有什么区别,为什么 Array(n).map 不执行?

解释 fill 为什么能补上 map 会跳过的缺失位置。

参考资料

  • MDN:fill

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 明确最后一个参数是终点而非数量
  3. 填充对象时确认是否需要独立实例
  4. 区间为空与数组为空都不会生成新容量
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑