js 嵌套数组赋值问题

2022-01-01 15:19:33 +08:00
 Turkestan
const arr = Array(2).fill(Array(2).fill(0));
// arr = [[0, 0], [0, 0]]
arr[1][1] = 1;

// expected:
[[0, 0], [0, 1]]

// current:
[[0, 1], [0, 1]]

为啥给数组第二个元素里的最后一项赋值为 1 , 前一个元素里的末项也会变成 1

正确解法没想到。。直接用上面第二行代码初始化二维数组,然后再进行赋值,完全没这个问题

2299 次点击
所在节点    JavaScript
13 条回复
dcsuibian
2022-01-01 15:23:00 +08:00
数组是引用、指针,arr[0]===arr[1]
Turkestan
2022-01-01 15:31:43 +08:00
用这种方法更新没问题:
const arr = [...Array(n)].map(() => Array(n).fill(0))
// arr = [[0, 0], [0, 0]]
arr[1][1] = 1;

console.log(arr)
// [[0, 0], [0, 1]]

没想通。。。
Yukee798
2022-01-01 15:35:33 +08:00
应该是 fill 方法的原因吧,Array(2).fill([0, 0]) 的时候,arr 里面存放的两个 [0, 0] 数组实际上是堆区里的同一个对象。
如果直接用 arr = [[0, 0], [0, 0]],那么里面的两个 [0, 0] 数组在堆区里面是两个不同的对象。
tedding
2022-01-01 15:35:37 +08:00
arr[0] arr[1] 指向同一个位置啊。fill 填充字符串没这个问题,填充引用类型这就是正确的行为。
Turkestan
2022-01-01 15:37:43 +08:00
看了一下 MDN 对 fill 方法中 value 的解释:
> Value to fill the array with. (Note all elements in the array will be this exact value.)

所以第一种赋值方法展开来应该是这样的:

arr[1][1] = 1;
// 改变了初始化时括号内的 Array(2).fill(0),即改变了第一个 fill 方法的 value.
arr[0] === arr[1] === Array(2).fill(0)
// 因此,arr[1][1] 发生变化后,arr[0][1] 也跟着发生变化了
tyx1703
2022-01-01 15:38:06 +08:00
fill 填充是浅拷贝

If the first parameter is an object, each slot in the array will reference that object.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill#description

我一般这样创建二维数组:

Array.from(new Array(m), () => Array.from(new Array(n), () => 0));
charlie21
2022-01-01 15:44:37 +08:00
fengfuliu
2022-01-01 15:59:18 +08:00
原因就是 fill 参数为引用类型时操作会有这个问题;可以这样 Array(2).fill(0).map(item=>Array(2).fill(0))
cansiny0320
2022-01-01 16:30:43 +08:00
const arr = new Array(2).fill(0).map(() => new Array(2).fill(0));
muzuiget
2022-01-01 16:41:35 +08:00
仔细看清楚 fill 的用法。
dany813
2022-01-02 16:09:46 +08:00
引用类型,不过挺有意思的,平时都注意不到
demonlin
2022-01-03 05:09:15 +08:00
2i2Re2PLMaDnghL
2022-01-03 19:15:48 +08:00
@tyx1703 准确地说 fill 填充不拷贝只复制引用

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/825658

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX