群里的小伙伴,提了一个问题。他用两种方法生成了两个二维数组,看着一样,表现却不一样。

第一种方法,比较传统。

1
2
3
4
5
6
7
8
9
10
11
12
function generate2dArray(len) {
const table = []
for(let i = 0; i < len; i++) {
const temp = []
for(let j = 0; j < len; j++) {
temp.push(0)
}
table.push(temp)
}
return table
}

第二种方式,非常的简短。

1
2
3
function generate2dArray(len) {
return Array(len).fill(Array(len).fill(0))
}

跑一下,第二个结果与第一个看似长得一样,但是第二个却是错误的。因为 fill 的是对同一个数组的引用。可以通过下面的代码进行验证。

1
2
const table = generate2dArray(2)
console.log(table[0] === table[1]) //true

那么有没有一种简短的方法可以生成这样一个二维数组呢,很容易就想到了用 map。于是我写了这样的代码。

1
2
3
function generate2dArray(len) {
return Array(len).map(() => Array(len).fill(0))
}

结果发现并不符合我的预期, map 里面的 callback 函数根本没有被调用。查了下资料发现 callback 函数只会在有值的索引上被调用。而使用 Array 函数生成的数组,默认是没有值的。所以把代码改成了这个样子。

1
2
3
function generate2dArray(len) {
return Array(len).fill(undefined).map(() => Array(len).fill(0))
}

将所有值变成 undefined,当然其他值也是可以的。于是乎我们就有了一个非常简单的方式生成一个二维的数组。