本文详解 JavaScript 中 Array.fill() 方法在填充引用数据类型(如对象或数组)时,所有元素指向同一内存地址的问题。通过示例展示修改单一元素导致整体变化的现象,并提供使用 map 函数生成独立引用或双重循环创建二维数组的解决方案,帮助开发者避开常见坑点。
JavaScript 解决 Array.fill() 参数为对象时指向同一引用地址的问题
在近期项目开发中,为了追求代码简洁,力求一行代码解决复杂逻辑,却意外踩到了 fill 方法的陷阱。
假设我们需要在一个数组中填充特定的指定数据,
Array(10).fill(1)此时若填充基本数据类型,结果会呈现为 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],即十个对应的数值 1。
然而,如果 fill 方法接收的参数是引用数据类型,数组内的所有元素将指向同一个内存地址。
let arr = Array(5).fill({}).map(it=>({}))
arr[0].a = 1输出结果示例为:[{a:1}, {a:1}, {a:1}, {a:1}, {a:1}]。
解决方案:利用 map 函数返回不同的引用地址,fill 方法的参数可以随意填写(只要不为空),关键在于 map 函数中返回的数据结构。
当类型为数组时:
let arr = Array(5).fill([]).map(it=>[])当类型为对象时:
Array(5).fill({}).map(it=>({}))注意:对象必须用小括号包裹,否则函数会将其误认为是函数体,且默认不写 return 时会返回 undefined。
补充:在 JavaScript 中使用 Array.fill() 初始化二维数组时需避开的坑
现有一个需求,需要创建一个 m*n 的二维数组,并预先填充为 false。
1.const P = new Array(3).fill(new Array(3).fill(false));
/*
[
[false, false, false],
[false, false, false],
[false, false, false]
]
*/2.
const P = new Array(3)
const obj = {name: 'qqq'}
P.fill(obj)
/*
[
[false, false, false],
[false, false, false],
[false, false, false]
]
*/
代码中的 1 和 2 部分展示了当我改变其中一个值时的情况:
P[0][0] = true;最终结果表现为:
/*
[
[true, false, false],
[true, false, false],
[true, false, false]
]
*/主要坑点在于:
如果 fill 的 value 参数是一个引用数据类型,则 fill 之后数组内的值都指向同一个内存地址。一旦修改其中一个元素的值,其他所有元素也会随之改变。
解决方法:
1. 利用双重 for 循环来创建二维数组。
for(var i = 0; i < 3; i++) {
arr[i] = new Array();
for(var j = 0; j < 3; j++) {
arr[i][j] = 0;
}
}2. 先使用空数组进行填充,然后再通过 map 遍历空数组,逐个添加元素。
const P = new Array(3).fill([]).map(() => new Array(3).fill(false));至此,关于 JavaScript 解决 Array.fill() 参数为对象指向同一个引用地址的文章介绍完毕,更多相关 js Array.fill() 参数为对象指向同一个引用地址内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!