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
正确解法没想到。。直接用上面第二行代码初始化二维数组,然后再进行赋值,完全没这个问题
1
dcsuibian 2022-01-01 15:23:00 +08:00 1
数组是引用、指针,arr[0]===arr[1]
|
2
Turkestan OP 用这种方法更新没问题:
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]] 没想通。。。 |
3
Yukee798 2022-01-01 15:35:33 +08:00 1
应该是 fill 方法的原因吧,Array(2).fill([0, 0]) 的时候,arr 里面存放的两个 [0, 0] 数组实际上是堆区里的同一个对象。
如果直接用 arr = [[0, 0], [0, 0]],那么里面的两个 [0, 0] 数组在堆区里面是两个不同的对象。 |
4
tedding 2022-01-01 15:35:37 +08:00 via iPhone 1
arr[0] arr[1] 指向同一个位置啊。fill 填充字符串没这个问题,填充引用类型这就是正确的行为。
|
5
Turkestan OP 看了一下 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] 也跟着发生变化了 |
6
tyx1703 2022-01-01 15:38:06 +08:00 2
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)); |
7
charlie21 2022-01-01 15:44:37 +08:00
|
8
fengfuliu 2022-01-01 15:59:18 +08:00
原因就是 fill 参数为引用类型时操作会有这个问题;可以这样 Array(2).fill(0).map(item=>Array(2).fill(0))
|
9
cansiny0320 2022-01-01 16:30:43 +08:00
const arr = new Array(2).fill(0).map(() => new Array(2).fill(0));
|
10
muzuiget 2022-01-01 16:41:35 +08:00
仔细看清楚 fill 的用法。
|
11
dany813 2022-01-02 16:09:46 +08:00
引用类型,不过挺有意思的,平时都注意不到
|
12
demonlin 2022-01-03 05:09:15 +08:00 1
|
13
2i2Re2PLMaDnghL 2022-01-03 19:15:48 +08:00
@tyx1703 准确地说 fill 填充不拷贝只复制引用
|