js数组

119 阅读3分钟

数组对象

  • 一种特殊的对象
  • js其实没有真正的数组
  • 只是用对象模拟数组

js数组非典型数组

典型数组

  • 元素的数据类型相同
  • 使用连续内存存储
  • 通过数字下标获取元素

1.jpg

js数组不是这样

2.jpg

  • 元素的数据类型可以不同
  • 内存不一定连续(对象随机存储)
  • 不能通过数字下标,而是通过字符串下标
  • js数组实际上是对象
  • 这意味着数组可以有任何key(key都是字符串)
  • 比如
  • let arr = [1,2,3]
  • arr['xxx'] = 1

创建一个数组

新建

  • let arr = [1,2,3]
  • let arr = new Array(1,2,3)
  • let arr = new Array(3) 参数只有一个,指长度

转化

  • let arr = '1,2,3'.split(',')//意为:用逗号分隔
  • let arr = '123'.split('')//意为:用空格分隔
  • Array.from('123')//最新ES标准提供把不是数组的东西尝试变成数组的方法——条件:0123下标;length属性

伪数组

  • let divList = document.querySelectorAll('div')
  • 伪数组的原型链中并没有数组的原型

一个数组没有数组共同属性(比如push)的数组就是伪数组

1.jpg

拿到伪数组就要先把它变成数组

1.jpg

2.jpg

3.jpg

合并;两个数组,得到新数组

  • arr1.concat(arr2)

1.jpg

截取一个数组的一部分

  • arr1.slice(1)//从第二个元素开始
  • arr1.slice(0)//全部截取 用于复制数组
  • 注意,js只提供浅拷贝slice(0),不提供专门的复制方法

2.jpg

3.jpg

增删改查数组中的元素

1. 删元素

跟对象一样

  • let arr = ['a','b','c']
  • delete arr['0']
  • arr//[empty,'b','c']
  • 神奇,数组的长度并没有变
  • 稀疏数组(没有好处,都是bug)

如果直接改length可以删元素吗

  • let arr = [1,2,3,4,5]
  • arr.length = 2
  • 居然可以?!js真神奇
  • 重要:不要随便改length

删除头部元素

  • arr.shift()//arr被修改,并返回被删元素

1.jpg

删除尾部元素

  • arr.pop()//arr被修改,并返回被删元素

2.jpg

删除中间元素

  • arr.splice(index,1)//删除index的一个元素
  • arr.splice(index,1,'x')//并在删除位置添加'x'
  • arr.splice(index,1,'x','y')//并在删除位置添加'x','y'

3.jpg

一个对象提供的函数就叫做API,如shift(),pop(),splice()

2. 查看所有元素

查看所有属性名

  • let arr = [1,2,3,4,5];arr.x = 'xxx'
  • Object.keys(arr)

1.jpg

  • for(let key in arr){console.log(${key}:${arr[ket]})}

针对普通对象可以,数组不建议使用

查看数字(字符串)属性名和值

for(let i = 0;i < arr.length;i++){

console.log(`${key}:${arr[key]}`)//打印属性名,属性值

}
  • ${}插入变量

1.jpg

2.jpg

  • 你要自己让i从0增长到length-1
arr.forEach(function(item,index){
console.log(`${index}:${item}`)
})

1.jpg

2.jpg

  • 也可以用forEach/map等原型上的函数

forEach是一个槛,自己写forEach才能理解forEach

function forEach(array,fn){               //forEach接受一个数组和函数
 for(let i = 0;i< array.length;i++){      //当运行forEach的时候,会遍历数组,把i增到length-1
   fn(array[i],i,array)                   //获取数组里的每一项,把每一项作为fn的参数传给fn
 }
}

1.jpg

2.jpg

  • forEach用for访问array的每一项
  • 对每一项调用fn(array[i],i,array)

3.jpg

  • 为什么要传入array数组本身呢?
  • 不为什么,规定,在特殊情况下会用到,大部分情况下只用传前两项(当前元素和下标)

两种方法for与forEach区别

  • 用for用break可以断,forEach要从头走到位 4.jpg
  • for后接块作用域,forEach后接函数作用域

3. 查看单个属性

跟对象一样

  • let arr = [111,222,333]
  • arr[0]

索引越界

  • arr[arr.length] === undefined
  • arr[-1] === undefined

举例

for(let i = 0;i <= arr.length;i++){    //i只能<length
console.log(arr[i].toString())
}
  • 报错:Cannot read property'toString'of undefined

5.jpg

1.jpg

  • 解决方法,哪个报错就打印哪个,如console.log(arr[1])

查找某个元素是否在数组里

  • arr.indexOf(item)//存在返回索引,否则返回-1

1.jpg

使用条件查找元素

  • arr.find(item=>item%2 === 0)//找第一个偶数

1.jpg

使用条件查找元素的索引

  • arr.findIndex(item=>item%2 === 0)
  • //找第一个偶数索引

6.jpg

4. 增加数组中的元素

1.jpg

2.jpg

3.jpg

尾部加元素

  • arr.push(newItem)//修改arr,返回新长度
  • arr.push(item1,item2)//修改arr,返回新长度

头部加元素

  • arr.unshift(newItem)//修改arr,返回新长度
  • arr.unshift(item1,item2)//修改arr,返回新长度

4.jpg

中间加元素

  • arr.splice(index,0,'x')//在index处插入'x'
  • arr.splice(index,0,'x','y')

5.jpg

5. 修改数组中的元素

6.jpg

反转顺序

  • arr.reverse()//修改原数组

7.jpg

经典面试题 如何反转字符串顺序

  • 先用API split把字符串换成数组
  • 用API reverse 反转数组顺序
  • 再把数组变回字符串

8.jpg

自定义顺序

  • arr.sort((a,b)=>a-b)

9.jpg

10.jpg

1.jpg

  • 简写

2.jpg

数组变化(不会改变原数组)

2.jpg

map

  • n变n

3.jpg

filter

  • n变少

1.jpg

reduce

  • n变1

1.jpg

  • 抢钱:包里初始值为零,抢劫一个乘客的钱放包里return,再继续抢,包里的钱加上当前正在抢的乘客的钱等于最终得到的钱

1.jpg [100,200,300,400].reduce((sum,money)=>{return sum = money},0)

  • 有reduce不需要map 1.jpg
  • 有reduce不需要filter

1.jpg

题目

第一题

  • 把数字变成星期

第二题

  • 找出所有大于60分的成绩

第三题

  • 算出所有数字之和

面试题

数据变换

let arr = [
{名称:'动物',id:1,parent:null},
{名称:'狗',id:2,parent:1},
{名称:'猫',id:3,parent:1}
]
数组变成对象
{
 id:1,名称:'动物',children:[
   {id:2,名称:'狗',children:null},
   {id:3,名称:'猫',children:null},
 ]
}