JavaScript 数组填充:Array.from 与 Array.fill 用法详解及核心区别

在日常开发中,我们经常需要快速创建指定长度的数组批量生成结构化数据 ,最常用的两个 API 就是 Array.fromArray.fill

很多新手容易踩坑:用 Array.fill 创建对象数组出现数据联动篡改、无法生成带索引的唯一数据、不知道两种 API 的适用场景。

今天一文讲透两者的基础用法、实战案例、底层原理、核心区别、避坑方案,彻底搞定数组初始化问题。

一、前置知识点:new Array() 的缺陷

首先我们先了解为什么不直接用 new Array(n) 创建数组:

javascript 复制代码
const arr = new Array(3)
 console.log(arr) // [empty × 3] 稀疏数组 
console.log(arr[0]) // undefined 
arr.map(item => item + 1) // 无效,遍历不到 empty 空位

问题new Array() 创建的是稀疏数组(empty 空位) ,无法被 mapforEach 正常遍历,几乎无法直接使用。

所以我们需要 Array.fromArray.fill 将稀疏数组转为可正常遍历的密集数组。

二、Array.fill 用法详解

1. 基础语法

arr.fill(value, start?, end?)

  • 作用:用一个固定值,填充数组的指定区间

  • 特性原地修改原数组

  • 默认区间:不传 start、end 则填充整个数组

2. 基础示例(基本数据类型)

javascript 复制代码
// 创建长度为5、全部为0的数组 
const arr = new Array(5).fill(0)
 console.log(arr) // [0, 0, 0, 0, 0] 
// 区间填充:下标1~3填充10
 const arr2 = [1,2,3,4,5] arr2.fill(10, 1, 4)
 console.log(arr2) // [1, 10, 10, 10, 5]

3. 致命坑:引用类型共享地址(高频踩坑)

fill 填充对象、数组 等引用类型时,所有元素指向同一个内存地址,改一个全联动!

javascript 复制代码
// 错误示范!!! 
const list = new Array(3).fill({ name: "测试" }) 
list[0].name = "修改第一个" 
console.log(list) // [{name: '修改第一个'}, {name: '修改第一个'}, {name: '修改第一个'}]

核心问题:fill 只会「赋值」,不会「新建对象」,所有元素共用同一个引用地址。

4. fill 适用场景

  • 快速生成固定长度的纯数字、字符串、布尔值数组

  • 批量重置数组内容、区间覆盖数组值

  • 不适合:生成对象数组、需要唯一数据、需要索引的场景

三、Array.from 用法详解

1. 基础语法

复制代码
Array.from(类数组/可迭代对象, 映射回调?)
  • 作用 :将类数组、稀疏数组转为密集数组,支持遍历映射

  • 特性 :返回新数组,不修改原数据

  • 回调优势 :自带 (item, index) 索引参数,支持自定义每一项数据

2. 基础用法:填充基础值

javascript 复制代码
// 生成长度5、全为1的数组 
const arr = Array.from({ length: 5 }, () => 1) console.log(arr) // [1,1,1,1,1]

3. 核心优势:生成独立对象数组(无引用联动)

这是 Array.from 吊打 fill 的核心场景!回调函数每次执行都会生成全新对象,内存地址独立。

javascript 复制代码
// 正确生成独立对象数组 
const list = Array.from({ length: 3 }, (_, index) => ({ id: index, title: `列表${index + 1}` }))
 list[0].title = "修改第一个" 
console.log(list) 
// [ {id:0, title:'修改第一个'}, {id:1, title:'列表2'}, {id:2, title:'列表3'} ]

4. 经典场景:用 index 生成唯一 ID

开发中批量造模拟数据、列表数据,基本都是用 Array.from

javascript 复制代码
// 生成10条带唯一id的模拟数据
 const mockData = Array.from({ length: 10 }, 
(_, i) => ({ 
  id: i + 1, 
// id从1开始自增 status: i % 2, content: `测试内容${i}` 
}))

5. Array.from 适用场景

  • 批量生成对象、数组等引用类型数组(无数据联动)

  • 需要根据索引 index 生成差异化数据

  • 类数组转换(arguments、DOM NodeList)

  • 生成结构化模拟数据、列表渲染数据源

四、Array.from VS Array.fill 核心区别(重点)

对比维度 Array.fill Array.from
是否修改原数组 原地修改原数组 返回新数组,不修改原数据
引用类型处理 所有元素共用同一内存地址,改一个全联动 每次回调生成新对象,数据完全独立
索引支持 无法获取索引,所有元素完全一致 自带 index 参数,可生成差异化数据
使用场景 填充基础固定值(数字、字符串) 生成结构化、差异化、对象数组数据
遍历能力 可将稀疏数组转为密集数组 原生支持遍历映射,功能更强

五、开发最佳实践(总结口诀)

  1. 简单定值填充(数字/字符串) :无脑用 Array.fill,简洁高效

  2. 对象/数组批量生成 :必须用 Array.from,杜绝数据联动 bug

  3. 需要自增 ID、差异化内容 :只用 Array.from 的 index 回调

  4. 绝对禁止:new Array(n).fill({}) 生成对象数组

六、补充:fill 如何正确生成对象数组?(不推荐)

如果非要用 fill 生成独立对象,必须配合 map 二次遍历,代码冗余,远不如 Array.from 简洁:

复制代码
// 冗余写法,不推荐 const list = new Array(3).fill(0).map((_, i) => ({ id: i }))

结论:生成结构化数据,优先 Array.from;纯定值填充,优先 fill

结尾

这两个数组 API 看似简单,但暗藏很多开发坑。掌握两者的本质区别,既能避免线上数据联动 bug,又能简化模拟数据、列表数据源的生成代码,大幅提升开发效率。

相关推荐
熊猫钓鱼>_>2 天前
ArkTS 方舟编程语言 · 原创快速入门教程
运维·架构·ts·harmonyos·arkts·鸿蒙·js
sugar__salt4 天前
Document 切割:RAG 知识库数据预处理实战
javascript·langchain·embedding·js·rag·cheerio
rockey6275 天前
基于AScript的JavaScript脚本语言发布啦
javascript·c#·.net·js·script
天若有情6738 天前
前端性能优化:从“按下预加载”到“AI级智能预判系统”
前端·性能优化·js·active·hover·首屏加载
H Journey9 天前
web开发学习:html、css、js
前端·css·html·js
Java小学生丶13 天前
分享一个 JS 鼠标跟随贪吃蛇背景库
js·美化
保持当下1 个月前
分享一些程序员很棘手但是却又简单的工具
程序员·免费·js·工具
Xzh04231 个月前
Web 前端开发 — 期末复习指南(Html、Css、Js)
css·html5·web·js·期末
蜂蜜黄油呀土豆1 个月前
Agent 循环:观察、思考、行动(ReAct 入门)
python·ai·大模型·react·js