一、数组基础知识
- 数组对象是一种特殊的对象
- JS没有真正的数组,只是用对象模拟
1、典型数组VS.JS数组
1.1、典型数组
- 元素的数据类型相同
- 使用连续的内存存储
- 通过数字下标获取元素

1.2、JS数组
- 元素的数据类型可以不同
- 内存不一定是连续的(对象是随机存储的)
- 通过字符串下标获取元素,意味着可以有任何key,'0'、'1'、'2'、'xxx'等

二、创建一个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()转化

- 并不是什么都能转,一般要满足有类似0,1,2下标,有长度length属性
3、合并
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长度,不推荐
let arr=[1,2,3,4,5]
arr.length=1
1.3、推荐方法
arr.shift()//删除头部元素
arr.pop()//删除尾部元素
- 删除中间元素
arr.splice(index,1)//删除index的一个元素
arr.splice(index,1,'x')//并在删除的位置添加一个'x'
arr.splice(index,1,'x','y')//或者添加两个元素,'x','y'
2、查
2.1、查看所有元素
2.1.1、不推荐方法1

2.1.2、不推荐方法2

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

2.1.4、高级用法forEach

- 如何理解——自己写一个for

- 原理:遍历数组,每次都调用这个函数
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())
}
- 如何查看错因:报哪里的错就在哪前打印出这个错误

2.2.3、查找某个元素是否在数组里
- arr.indexOf(item)//存在返回索引,否则返回-1
- 使用条件查找,arr.find(item=>item%2===0)//查找偶数,等同于arr.find(function(x){return x%2===0})
- 使用条件查找元素的索引,arr.findIndex(item=>item%2===0)//查找偶数的索引,等同于arr.findIndex(function(x){return x%2===0})
- 以上三条均返回第一个找到的元素或索引
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()
- 经典题目

4.2、自定义数组元素顺序

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

- 若手动改为a>b,返回-1;a=b,返回0;a<b,返回1,此为从大到小排序
- 以上函数代码可简写为
arr.sort((a,b)=>a-b)
- eg:对象作为数组元素

- 以上函数代码可简写为
arr.sort((a,b)=>a.score-b.score),这是默认从小到大排序
四、数组变换
1、map
- n变n,一一映射,如输出各item的平方

2、filter
- n变少,如只输出偶数

3、reduce
- n变1,如求item之和

- 上述代码可简写成
arr.reduce((sum,item)=>{return sum+item},0),这个0是sum的初始值
3.1、reduce的升级应用
- n变n也可以用reduce

- n变少也可以用reduce

- 上述代码可优化成

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