关于一维数组的介绍,可以查看我的另一篇博客
JS中的数组–Array对象及其方法
一、二维数组的创建
让我们首先回顾一下JS中一维数组的创建并引起二维数组的创建:
1、字面量创建:
二维数组也可以通过字面量进行创建
let arr2d=[[1,2],[3,4]];
2、Array()
方法嵌套
二维数组其实就是在一维数组中装入嵌套的一维数组而形成
let arr2d=Array(5);
for(let i=0;i<5;i++){
arr2d[i]=[1,i];
}
或
let arr2d=Array(5).fill(0);
arr2d.forEach((a,b)=>arr2d[b]=[1,b]);
或
let arr2d=Array(5).fill(0).map((a,b)=>[1,b]); //推荐
得到的结果都是
[[1,0],[1,1],[1,2],[1,3],[1,4]]
第一种是先定义一个一维数组,然后将一维数组的值赋值为一个数组,最终嵌套为二维数组
第二种使用了fill()
进行了填充,然后使用forEach()
进行遍历赋值,那么其中有几个小知识点:
- 为什么需要
fill()
进行填充?因为如果不填充的话返回数组就是空槽,而forEach()
和map()
是不会访问空槽的,无法遍历 - 为什么不直接使用数组作为参数的
fill()
来填充数组,比如fill([ ])
?因为fill()
函数的参数为对象时,所有的元素都会引用这个数组对象,修改一个值,其他所有的元素都会跟着变,这明显不是我们想要的结果。 - 为什么不链式调用,像
Array(5).fill(0).forEach()
这样?因为forEach()
函数没有返回值,链式调用的话,我们得不到结果。
第三种最简洁了,我们来解释下这些map()
和forEach()
中的a
,b
是啥,
- 第一个参数代表当前遍历元素的
值
, - 第二个参量了,代表为当前遍历元素的
索引
, - 那么如果有第三个参数
c
呢?那么代表的是执行这个函数的当前数组对象
。 - map的返回数组是由各个返回值组成的
下面介绍其他可能的错误的初始化方法
错误1:用数字初始化一维数组后,直接使用二维数组的方法进行赋值
let arr=Array(5).fill(0);
for(let i=0;i<3;i++){
arr[0][i]=i;
}
错误的点在于,arr[0]=0,其值是一个Number
,而Number
不是对象,没有嵌套值,更无法通过索引访问。
正确方法是:
let arr=Array(5).fill(0).map(()=>[]);
for(let i=0;i<3;i++){
arr[0][i]=i;
}
区别在于,此时arr[0]=[];其值是一个空数组,属于是对象,可以通过arr[0][i]来赋值
多维数组的创建(比如三维)
let arr=Array(5).fill(0).map(()=>[[]]);
二、二维数组的访问和修改
和其他语言类似,通过二维索引进行访问和修改
三、二维/多维数组的复制
由于数组对象的复制操作均是浅拷贝
,所以对二维数组或者多维数组底层值的直接修改,均会使原数组也发生变化
let arr2d=[[1,2],[3,4]];
let nums=Array.from(arr2d);
nums[0][0]=100;
console.log(nums); //[[100,2],[3,4]]
console.log(arr2d); //[[100,2],[3,4]]
赋值操作就更不用说了,本就是复制的引用
let arr2d=[[1,2],[3,4]];
let nums=arr2d;
nums[0][0]=1000;
console.log(nums); //[[1000,2],[3,4]]
console.log(arr2d); //[[1000,2],[3,4]]
要想使用独立的二维数组数据,那么需要对原数组进行深拷贝
:
JSON.parse(JSON.stringify())
let arr2d=[[1,2],[3,4]];
let nums=JSON.parse(JSON.stringify(arr2d));
nums[0][0]=10;
console.log(nums); //[[10,2],[3,4]]
console.log(arr2d); //[[1,2],[3,4]]
structuredClone()
let arr2d=[[1,2],[3,4]];
let nums=structuredClone(arr2d); //此方法为web api方法
nums[0][0]=10;
console.log(nums); //[[10,2],[3,4]]
console.log(arr2d); //[[1,2],[3,4]]
手动递归实现深拷贝
递归到对象的底层,拷贝底层值