返回

Array.fill(new Array()): 初始化二维数组的正确方法

前端

在JavaScript开发中,经常会遇到需要初始化一个二维数组的情况。然而,使用 Array.fill(new Array()) 来初始化二维数组的方法可能会导致意料之外的结果。本文将详细解释这一问题的原因,并提供正确的解决方案。

问题描述

开发者经常会尝试使用以下代码来初始化一个二维数组:

let rows = 3;
let cols = 4;
let matrix = Array.from({ length: rows }, () => new Array(cols));
console.log(matrix);

然而,这种方法会产生意料之外的结果。让我们看看为什么。

问题分析

错误示例

let rows = 3;
let cols = 4;
let matrix = Array.from({ length: rows }, () => new Array(cols));
console.log(matrix);

上述代码的输出如下:

[
  [ undefined, undefined, undefined, undefined ],
  [ undefined, undefined, undefined, undefined ],
  [ undefined, undefined, undefined, undefined ]
]

原因解析

问题在于 Array.from 方法中的第二个参数是一个回调函数,该回调函数会在每次迭代时被调用。而 new Array(cols) 创建的是一个长度为 cols 的空数组,但并没有实际填充任何值,因此每个子数组都是未定义的。

正确解决方案

为了正确初始化一个二维数组,我们需要确保每个子数组都被正确地填充。可以使用 Array.frommap 方法来实现这一点。

修改后的代码

let rows = 3;
let cols = 4;
let matrix = Array.from({ length: rows }, () => Array(cols).fill(0));
console.log(matrix);

原理解释

  1. Array.from({ length: rows }) 创建一个长度为 rows 的数组。
  2. () => Array(cols).fill(0) 是一个回调函数,它在每次迭代时被调用,返回一个长度为 cols 且所有元素都为 0 的数组。
  3. Array(cols).fill(0) 创建一个长度为 cols 的数组,并用 0 填充每个元素。

这样,我们就得到了一个正确初始化的二维数组:

[
  [ 0, 0, 0, 0 ],
  [ 0, 0, 0, 0 ],
  [ 0, 0, 0, 0 ]
]

引用数据类型的概念

在JavaScript中,数组是引用数据类型。这意味着当你创建一个数组并将其赋值给另一个变量时,这两个变量实际上引用的是同一个数组对象。理解这一点对于避免常见的错误非常重要。

示例说明

let arr1 = [1, 2, 3];
let arr2 = arr1;
arr2.push(4);
console.log(arr1); // [1, 2, 3, 4]

在这个例子中,arr1arr2 都引用了同一个数组对象。因此,对 arr2 的任何修改都会反映在 arr1 上。

安全建议

为了避免意外修改共享的数组对象,可以使用深拷贝(deep copy)来创建独立的副本。例如:

let arr1 = [1, 2, 3];
let arr2 = JSON.parse(JSON.stringify(arr1));
arr2.push(4);
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [1, 2, 3, 4]

通过这种方式,arr1arr2 将不再共享同一个数组对象,从而避免了意外修改的问题。

总结

通过本文,我们了解了使用 Array.fill(new Array()) 初始化二维数组时可能遇到的问题,并提供了正确的解决方案。理解引用数据类型的概念以及如何进行深拷贝,可以帮助开发者编写更健壮的代码。希望这篇文章对你有所帮助!