JS数组

96 阅读3分钟

JS数组

JS的数组不是典型的数组

  • 典型的数组

    • 元素的数据类型相同
    • 使用连续的内存存储
    • 通过数组下标获取元素
  • 但JS的数组不这样

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

创建一个数组

  • 新建
 let arr = [1,2,3];
 let arr = new Array(1,2,3)
 let arr = Array(3);
  • 转化
 let arr = '1,2,3'.split(',')
 let arr = '123'.split('')
 Array.from('123')
  • 伪数组
 let divList = document.querySelector('div')

伪数组的原型链中并没有数组的原型,因为它的原型直接指到了Object

没有数组共用属性的数组就是伪数组

  • 合并两个数组,得到新数组
 arr3.concat(arr2)
  • 截取一个数组的一部分
 arr1.slice(1)
 arr1.slice(0)
 //注意,JS只提供浅拷贝
删元素
  • 跟对象一样(不推荐)
 let arr = ['a','b','c']
 delete arr ['0']
 //arr[empty,'b','c'] 数组的长度没有发生变化;稀疏数组
  • 如果直接更改length可以删除元素么

可以,但是不要随便更改length

  • 删除头部的元素
 arr.shift()//arr被修改,并返回被删元素
  • 删除尾部的元素
 arr.pop()//arr被修改,并返回被删元素
  • 删除中间的元素
   arr.splice(index) //删除index的一个元素
 ​
   arr.splice(index,1,'x')//并在删除位置添加‘x’
 ​
   arr.splice(index,1,'x','y')//并在删除位置添加'x','y'

查看所有属性

  • 查看所有属性名
 let arr = [1,2,3,4,5];arr.x=‘xxx’
 Object.keys(arr)
  • 查看数字(字符串)属性名和值

你可以自己让i从0增长到length-1,并返回arr中对应的值

 for(let i = 0;i<arr.length;i++){
   console.log(`${i}:${arr[i]}`);
 }//使用for循环访问数组是一种常规的形式

或者也可以使用forEach/map等原型上的函数

 arr.forEach(function(x,y){
   console.log(`${y}:${x}`)
 })

自己实现的forEach函数

 function forEach(array,fn){
    for(let i =0;i<array.length;i++){
      fn(array[i],i,array);
    }
 }
 ​
 forEach(['a','b','c'],function(x,y,z){
   console.log(x,y,z)
 })

那么for循环和forEach的区别是什么

通常来说没有本质的区别,在for循环中可以使用break;而forEach中没有break,for循环是关键字,在内容中没有函数作用域只有块级作用域,而forEach是函数,是函数作用域

查看单个属性

索引越界
 arr[arr.length] === undefined
 arr[-1] === undefined
 ​
 //举例
 let arr =[1,2,3]
 for(let i = 0;i<=arr.length;i++){
   console.log(arr[i].toString())
 }
 //Cannot read properties of undefined (reading 'toString') 数组越界

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

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

使用条件查找元素

 arr.find(function(x){
     return x%2===0;
 })//找到第一个偶数
 arr.findIndex(function(x){
     return x%2===0;
 })//返回索引

使用条件查找元素的索引

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

增加数组中的元素

不推荐的方法

 arr = ['a','b','d']
 arr.['100']=100;
 //(101['a', 'b', 'c', 'd', 空属性 × 96, 100] 数组会变为稀疏数组,中间会留下空间
  • 在尾部添加元素
 arr.push(newItem) //修改arr,返回新长度
 arr.push(item1,item2) //修改arr,返回新长度
  • 在头部加元素
 arr.unshift(newItem)
  • 在中间添加元素
 arr.splice(index,0,'x')//在index处插入'x'
 arr.splice(index,0,'x','y')

修改数组中的元素

  • 反转顺序
 arr.reverse()//修改原数组
  • 自定义顺序
 let arr = [1,2,3,4,5]
 arr.sort() //(5[1, 2, 3, 4, 5]
 ​
 //sort()中可以自己传入一个函数,指定排序的方式
 arr.sort(function(a,b){
     if(a<b){
         return 1;
     }else if(a===b){
         return 0;
     }else return -1
 })//(5[5, 4, 3, 2, 1]
 ​
 //通过访问对象中的元素比较大小
 let arr2=[{score:98},{score:97},{scroe:99s}]
 arr2.sort(function(a,b){
     if(a.score<b.score){
         return 1
     }else if(a.score===b.score){
         return 0
     }else{
         return -1
     }
 })
 //) [{…}, {…}, {…}]0: {score: 99}1: {score: 98}2: {score: 97}length: 3[[Prototype]]: Array(0)
 ​
 //一种比较简便的写法
 arr2.sort((a,b)=>a.score-b.score)

数组变换

  • map n变n
  • filter n变少
  • reduce n变1
 let arr = [1,2,3,4,5,6]
 ​
 //map 一一映射
 arr.map(item=>item*item) //(6) [1, 4, 9, 16, 25, 36]
 ​
 //filter 进行筛选
 arr.filter(item=>item%2===0) //(3) [2, 4, 6]
 ​
 //reduce 合成
 arr.reduce((sum,item)=>{return sum+item},0)
 ​
 //通过reduce实现上面map和filter的效果,reduce的效果十分强大,通过reduce实现item的平方
 arr.reduce((result,item)=>{return result.concat(item*item)},[])
 //(6) [1, 4, 9, 16, 25, 36]
 ​
 //通过reduce实现筛选
  arr.reduce((result,item)=>{
     if(item%2===1){
         return result;
     }else {
         return result.concat(item)
     }
 },[])
 //(3) [2, 4, 6] 
 ​
 //当然这段代码可以简化为
  arr.reduce((result,item)=>item%2===1?result:result.concat(item),[])
 ​
 //还可以再简化
 arr.reduce((result,item)=>result.concat(item%2===1?[]:item),[])