ES6数组fill方法全解析
时间:2025-07-14 16:39:28 117浏览 收藏
想要快速初始化或重置数组?ES6的`fill()`方法是你的不二之选!本文将深入解析`fill()`方法的用法,包括其三个参数:`value`(必填,填充值)、`start`(可选,起始索引)和`end`(可选,结束索引)。通过实例讲解,让你轻松掌握如何使用`fill()`方法创建固定长度数组、重置数组特定部分、在算法中初始化全值数组以及填充占位符数组等常见应用场景。同时,我们还将对比`fill()`与`Array.from()`和`map()`的区别,并提醒使用`fill()`时需要注意的“坑”,例如引用类型的浅拷贝问题。掌握`fill()`方法,让你的JavaScript数组操作更加高效便捷!
fill()方法常见应用场景有四:1.创建并初始化固定长度数组;2.重置数组特定部分;3.算法中使用全值数组作为初始状态;4.填充占位符或默认值数组。例如new Array(10).fill(0)快速生成十个零,gameBoard.fill(null, 2, 5)清空棋盘部分区域,visitedNodes = new Array(100).fill(false)标记节点访问状态,placeholders = Array(5).fill('待定')生成默认占位数组。
在ES6中,如果你想快速地用一个指定的值填充数组的全部或部分元素,Array.prototype.fill()
方法就是你的得力助手。它直接在原数组上进行操作,非常高效。

解决方案
fill()
方法接受三个参数:value
、start
和end
。
value
: 用来填充数组的值。这是必填项。start
: 可选参数,填充的起始索引(包含)。如果省略,默认为0。end
: 可选参数,填充的结束索引(不包含)。如果省略,默认为array.length
。
这个方法会修改原数组,并且返回被修改后的数组。

举个例子:
// 填充整个数组 const arr1 = [1, 2, 3, 4, 5]; arr1.fill(0); // arr1 现在是 [0, 0, 0, 0, 0] console.log(arr1); // 填充部分数组 const arr2 = ['a', 'b', 'c', 'd', 'e']; arr2.fill('x', 1, 4); // 从索引1开始,到索引4(不包含)结束 // arr2 现在是 ['a', 'x', 'x', 'x', 'e'] console.log(arr2); // 只指定起始索引 const arr3 = [10, 20, 30, 40, 50]; arr3.fill(99, 2); // 从索引2开始,填充到数组末尾 // arr3 现在是 [10, 20, 99, 99, 99] console.log(arr3); // 负数索引:从数组末尾开始计算 const arr4 = [1, 2, 3, 4, 5]; arr4.fill(7, -3, -1); // 从倒数第三个(索引2)开始,到倒数第一个(索引4,不包含)结束 // arr4 现在是 [1, 2, 7, 7, 5] console.log(arr4);
我个人觉得,这个方法最妙的地方就在于它的简洁性。你想想看,如果不用它,你可能得写个循环,或者用map
之类的,但fill
就直接很多,一行代码就能搞定很多初始化或者重置数组的任务。

fill() 方法有哪些常见的应用场景?
fill()
方法虽然看起来简单,但在实际开发中却有不少实用的场景。最直接的,当然是数组的初始化。比如,你需要一个固定长度的数组,并且每个元素都想先赋个默认值,new Array(length).fill(value)
简直是天作之合。我经常用它来快速创建一个空的、但有预设大小的数组,比如在处理某些固定大小的数据块时,或者为后续的计算预留空间。
// 场景一:创建并初始化一个固定长度的数组 const tenZeros = new Array(10).fill(0); // tenZeros: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] console.log(tenZeros); // 场景二:重置数组的特定部分 const gameBoard = ['X', 'O', null, 'X', null, 'O', null, null, null]; // 假设游戏结束,我们想清空棋盘的某个区域 gameBoard.fill(null, 2, 5); // 清空索引2到4的区域 // gameBoard: ['X', 'O', null, null, null, 'O', null, null, null] console.log(gameBoard); // 场景三:在某些算法中,需要一个全为某个值的数组作为初始状态 const visitedNodes = new Array(100).fill(false); // 图遍历中标记节点是否访问过 console.log(visitedNodes.slice(0, 5)); // 只看前5个 // 场景四:填充新的数组,用于占位符或默认值 const placeholders = Array(5).fill('待定'); // placeholders: ['待定', '待定', '待定', '待定', '待定'] console.log(placeholders);
它特别适合那些需要快速、批量地将数组元素统一为某个值的场景,减少了手动循环的繁琐。
fill() 方法与 Array.from() 或 map() 有何不同?
这是一个非常好的问题,因为它们都能对数组进行操作,但内在机制和适用场景却大相径庭。理解这些差异,能帮助你选择最合适的工具。
首先,最核心的区别在于可变性(Mutability)。
fill()
:它是一个原地修改数组的方法。这意味着它会直接改变调用它的那个数组。如果你不希望原始数组被修改,那么fill()
可能不是最佳选择,或者你需要先创建一个副本。map()
:它是一个不可变的方法。map()
会遍历数组的每个元素,并根据你提供的回调函数返回一个新的数组,而不会修改原数组。这是函数式编程中非常推崇的特性,因为它避免了副作用,让代码更可预测。Array.from()
:这个方法主要是用来从一个类数组对象或可迭代对象创建一个新的、浅拷贝的数组实例。它也可以接受一个映射函数,这样在创建新数组的同时,可以对元素进行转换。它同样不会修改原数据源。
再来看目的和功能:
fill()
:它的主要目的是用一个相同的值去填充数组。它不关心数组原有的元素是什么,只是简单地覆盖。map()
:它的目的是根据一个转换规则(回调函数)来生成一个新数组。每个新元素都由原数组对应元素经过转换而来,所以它更侧重于“转换”而非“填充”。Array.from()
:它的目的在于创建新数组。它可以从各种来源(如字符串、Set、Map、NodeList)创建数组,或者像new Array(length).fill(value)
那样,但更灵活的是它能结合映射函数,在创建时就进行复杂的初始化。
const originalArr = [1, 2, 3]; // 使用 fill() - 修改原数组 const filledArr = [...originalArr]; // 先复制一份,避免直接修改originalArr filledArr.fill(0); console.log('fill() 结果:', filledArr, '原数组:', originalArr); // fill() 结果: [0, 0, 0] 原数组: [1, 2, 3] // 使用 map() - 返回新数组,不修改原数组 const mappedArr = originalArr.map(item => item * 2); console.log('map() 结果:', mappedArr, '原数组:', originalArr); // map() 结果: [2, 4, 6] 原数组: [1, 2, 3] // 使用 Array.from() - 创建新数组 const newArrFromOriginal = Array.from(originalArr); console.log('Array.from() 结果:', newArrFromOriginal, '原数组:', originalArr); // Array.from() 结果: [1, 2, 3] 原数组: [1, 2, 3] // Array.from() 结合映射函数 const newArrWithMap = Array.from({ length: 3 }, (_, i) => i + 10); console.log('Array.from() with map 结果:', newArrWithMap); // Array.from() with map 结果: [10, 11, 12]
选择哪个方法,完全取决于你的需求:是想原地修改,还是想生成一个新数组?是想用同一个值填充,还是想根据某种规则转换每个元素?
使用 fill() 方法时需要注意哪些潜在的“坑”?
虽然fill()
方法用起来很方便,但它也有一些需要特别留心的地方,否则可能会踩到一些“坑”。我个人在使用它的时候,最常遇到的一个误区就是关于引用类型的值。
引用类型值的“浅拷贝”问题: 这是最常见也是最容易让人困惑的地方。当你用一个对象(包括数组、对象字面量等)去填充数组时,
fill()
并不会为每个位置创建一个新的对象实例,而是将同一个对象的引用填充到数组的每个位置。这意味着数组中的所有元素都指向同一个对象。const arrWithObject = new Array(3).fill({}); // 用一个空对象填充 console.log(arrWithObject); // [ {}, {}, {} ] // 现在,尝试修改第一个元素里的属性 arrWithObject[0].name = 'Alice'; console.log(arrWithObject); // 结果是:[ { name: 'Alice' }, { name: 'Alice' }, { name: 'Alice' } ] // 所有的元素都被修改了!
你看,如果你期望每个元素都是独立的空对象,那这样就出问题了。因为它们都指向堆内存中的同一个对象实例。如果你需要每个元素都是独立的引用类型,你可能需要用
Array.from()
结合映射函数来创建:const independentObjects = Array.from({ length: 3 }, () => ({})); independentObjects[0].name = 'Bob'; console.log(independentObjects); // 结果是:[ { name: 'Bob' }, {}, {} ] // 这才是我们想要的效果,每个对象都是独立的。
对空位(Sparse Arrays)的处理:
fill()
方法会填充数组中的所有索引,包括那些在稀疏数组中可能存在的“空位”(empty slots)。它会把这些空位也填充上指定的值。const sparseArr = [1, , 3]; // 索引1是空位 sparseArr.fill(0); console.log(sparseArr); // [0, 0, 0]
这通常不是问题,但如果你依赖于空位的特性(比如在某些老旧代码或特定场景下),需要注意
fill()
会消除这些空位。负数索引的计算: 虽然我在前面提到了负数索引,但有时初学者会混淆它的计算方式。负数索引是从数组末尾开始计算的,
-1
表示最后一个元素,-2
表示倒数第二个,以此类推。如果计算出的实际索引超出了数组范围,它们会被调整到0或array.length
。const myArr = [1, 2, 3, 4, 5]; myArr.fill(99, -10); // -10 经过计算小于0,所以实际从索引0开始 console.log(myArr); // [99, 99, 99, 99, 99] const anotherArr = [1, 2, 3, 4, 5]; anotherArr.fill(88, 2, -10); // 结束索引-10经过计算小于起始索引2,所以不进行任何填充 console.log(anotherArr); // [1, 2, 3, 4, 5]
当
start
大于或等于end
时,fill()
方法不会做任何操作。
总的来说,fill()
是一个非常实用的方法,但关键在于理解它的原地修改特性,以及处理引用类型值时的“浅拷贝”行为。只要避开这些小“坑”,它就能大大提高你的开发效率。
今天关于《ES6数组fill方法全解析》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
255 收藏
-
323 收藏
-
433 收藏
-
245 收藏
-
379 收藏
-
444 收藏
-
110 收藏
-
180 收藏
-
272 收藏
-
479 收藏
-
486 收藏
-
208 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习