JS数组

88 阅读4分钟

一、数组基础知识

  • 数组对象是一种特殊的对象
  • JS没有真正的数组,只是用对象模拟

1、典型数组VS.JS数组

1.1、典型数组
  • 元素的数据类型相同
  • 使用连续的内存存储
  • 通过数字下标获取元素 微信图片_20230314120029.jpg
1.2、JS数组
  • 元素的数据类型可以不同
  • 内存不一定是连续的(对象是随机存储的)
  • 通过字符串下标获取元素,意味着可以有任何key,'0'、'1'、'2'、'xxx'等 微信图片_20230314120537.jpg

二、创建一个JS数组

1、新建

  • let arr=new Array(1,2,3)//元素为1,2,3
  • let arr=new Array(3)//长度为3
  • let arr=[1,2,3]//简写

2、转化

2.1、将有逗号的字符串用逗号隔开成为数组[1,2,3]
let str='1,2,3'
str.split(',')
2.2、将没有逗号的字符串用空字符串隔开成为数组[1,2,3]
let str2='123'
str2.split('')
2.3、直接用Array.from()转化

微信图片_20230314131829.png

  • 并不是什么都能转,一般要满足有类似0,1,2下标,有长度length属性

3、合并

  • arr1.concat(arr2)

4、截取

  • arr1.slice(1)//从第二个元素开始截取后面的(含第二个)
  • arr1.slice(0)//从第一个元素开始(复制一个数组)
  • 以上操作,均不会改变原数组
  • 另,JS只提供浅拷贝

5、伪数组

  • 其原型链中并没有数组的原型(数组是有两层prototype,一层装push、pop等,一层装toString、valueOf等)
  • array={0:'a',1:'b',2:'c',3:'d',length:4},这个数组就没有push、pop等属性
  • let divList=document.querySelectorAll('div'),伪数组,进行Array.from()操作,let divArray=Array.from(divList),变成了数组,有push、pop等属性
  • 总结:没有数组共有属性的‘数组’,就是伪数组

三、增删改查,数组中的元素

1、删

1.1、用删对象的方法,delete,不推荐
  • 如下,会得到[empty,'b','c'],长度仍为3,若都删了,则[empty*3],如此:只有长度,无对应下标的数组,称为稀疏数组
let arr=['a','b','c']
delete arr['0']
1.2、直接改length长度,不推荐
  • 如下,会得到[1],但不要随便改length
let arr=[1,2,3,4,5]
arr.length=1
1.3、推荐方法
  • arr.shift()//删除头部元素
  • arr.pop()//删除尾部元素
  • 删除中间元素
  1. arr.splice(index,1)//删除index的一个元素
  2. arr.splice(index,1,'x')//并在删除的位置添加一个'x'
  3. arr.splice(index,1,'x','y')//或者添加两个元素,'x','y'
  • 以上,其length也相对应改变

2、查

2.1、查看所有元素
2.1.1、不推荐方法1

微信图片_20230314135747.jpg

  • 不能同时查看属性名和值
2.1.2、不推荐方法2

微信图片_20230314140244.jpg

  • 输出的是属性名,且还输出了x,不想让x也输出
  • 可以改为for(let i=0;i<arr.length;i++){console.log(i)},此时输出是0,1,2,3,4,但还只是属性名
2.1.3、推荐使用for

微信图片_20230314141440.png

2.1.4、高级用法forEach

微信图片_20230314163618.png

  • 如何理解——自己写一个for 微信图片_20230314164830.png
  • 原理:遍历数组,每次都调用这个函数
2.1.5、以上两种写法的区别(for、forEach)
  • 一般情况下,这两种写法几乎等价
  • 但for循环里可有break、continue等,而forEach只是一个普通函数,for的功能会更强大些
  • for是块级作用域,forEach是函数作用域
2.2、查看单个属性
2.2.1、查看
let arr=[1,2,3]
arr[0]
2.2.2、索引越界
  • arr[arr.lengtn]===undefined、arr[-1]===undefined
  • 如下会报错:cannot read property 'toString' of undefined(读取了undefined的toString,并非toString是undefined),eg:x.toString(),如果x是undefined,则报这个错
let arr=[1,2,3]
for(let i=0;i<=arr.length;i++){
  console.log(arr[i].toString())
}
  • 如何查看错因:报哪里的错就在哪前打印出这个错误 微信图片_20230314171340.png
2.2.3、查找某个元素是否在数组里
  1. arr.indexOf(item)//存在返回索引,否则返回-1
  2. 使用条件查找,arr.find(item=>item%2===0)//查找偶数,等同于arr.find(function(x){return x%2===0})
  3. 使用条件查找元素的索引,arr.findIndex(item=>item%2===0)//查找偶数的索引,等同于arr.findIndex(function(x){return x%2===0})
  4. 以上三条均返回第一个找到的元素或索引

3、增

3.1、不推荐使用
let arr=[1,2,3,4,5]
arr[5]=6
  • 以上得到[1,2,3,4,5,6],添加元素的同时改变长度,看起来是对的
  • arr[100]=100,得到[1,2,3,4,5,6,empty*94,100],此时变成了长度为101的稀疏数组
3.2、推荐使用
  • arr.push(6,7)//返回新长度7,在尾部加元素,[1,2,3,4,5,6,7]
  • arr.unshift('x','y','z')//返回新长度,在头部加元素,['x','y','z',1,2,3,4,5,6,7]
  • arr.splice(6,0,3.5)//在中间加,(与删元素作比较,在下标为6的位置删除0个数据,然后在此位置加3.5)

4、改

4.1、反转
  • arr.reverse()
  • 经典题目 微信图片_20230314231131.jpg
4.2、自定义数组元素顺序

微信图片_20230314231327.png

  • arr.sort()默认元素从小到大排序
  • 解析如下:sort()函数去比较两数之间大小,若a>b,返回1;若a=b,返回0;若a<b,返回-1,此为从小到大排序,这是JS默认

微信图片_20230314232136.png

  • 若手动改为a>b,返回-1;a=b,返回0;a<b,返回1,此为从大到小排序
  • 以上函数代码可简写为arr.sort((a,b)=>a-b)
  • eg:对象作为数组元素 微信图片_20230314233144.png
  • 以上函数代码可简写为arr.sort((a,b)=>a.score-b.score),这是默认从小到大排序

四、数组变换

1、map

  • n变n,一一映射,如输出各item的平方 微信图片_20230314233559.png

2、filter

  • n变少,如只输出偶数 微信图片_20230314233830.png

3、reduce

  • n变1,如求item之和 微信图片_20230314234217.png
  • 上述代码可简写成arr.reduce((sum,item)=>{return sum+item},0),这个0是sum的初始值
3.1、reduce的升级应用
  • n变n也可以用reduce 微信图片_20230314234857.jpg
  • n变少也可以用reduce 微信图片_20230314235128.jpg
  • 上述代码可优化成 微信图片_20230314235339.jpg

4、以上map、filter、reduce,会生成新的数组,旧数组不变