JavaScript 数组

159 阅读5分钟

JS数组

数组对象,一种特殊的对象
JS其实没有真正的数组,是JS用对象模拟的,用key和value模拟的,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 = new Array(3)
创建一个字符串长度为3,内容是空的数组,只有一个数字时代表长度

把字符串变成数组

let arr ='1,2,3'.split(',')     
split接收参数,用什么来分隔

等于:arr.split(',')
let arr = '123'.split('')

Array.from('123')                     
from 从什么地方得到一个数组

from 把不是数组的东西尝试变成数组,不是所有的东西都能被from变成数组,满足2个条件:
这个对象有0,1,2,3 这样的下标,有length 长度属性

伪数组

没有数组共有属性的数组就是伪数组,原型链中没有数组的原型就是伪数组
伪数组的原型链中并没有数组的原型,它的原型直接指向对象的原型,少一层

let divList =document.querySelectorAll('div')
用在这个方法获取的div就是伪数组
没有push等原型属性,可以使用Array.from(divList)变成数组,就有了push等属性

创建一个数组其它方法

arr1.concat(arr2)
合并两个数组,得到新数组,concat连接,arr1和arr2的值没变,合成了新数组

arr1.slice(1)  
截取一个数组的一部分,slice切,从下标1开始,原来的数组不变

arr1.slice(0)                            
全部截取,经常用于复制

let arr2 = arr1.slice(0)          
JS只提供浅拷贝,创建一个arr2,把arr1复制进去

增删改查,数组中的元素

删除元素

arr.shift()
删除头部的元素,arr被修改,并返回被删元素,shift往上抬的意思,超出部分就删除了

arr.pop()                      
删除尾部元素,arr被修改,并返回被删元素

arr.splice(index,1)         
删除中间元素,删除index位置的一个元素
arr.splice(2,3)
在2的位置删除3个元素

arr.splice(index,1,'x')
在删除的位置上加x

arr.splice(index,1,'x','y')      
在删除的位置上加x,y

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

for(let i=0; i<arr.length; i++){
    console.log(`${i}:${arr[i]}`)
    }

arr.forEach(function(item,index){
    console.log(`${index}:${item}`)
  }
)               
遍列数组,每一次都调用这个函数,使用Each/map等原型上的属性

console.log(`${i}:${arr[i]}`)
$可以插入变量,变量的key变量的value

forEach(['a','b','c'],function(x,y,z){console.log(x,y,z)})
x数组中的元素,y是下标,z是数组本身

forforEach的区别
for是关键字,块作用域,支持break,continue,停止循环;forEach是函数,不支持break

function forEach(array,fn){
  for(let i=0; i<array.length; i++){
    fn(array[i],i,array)
    }
}
forEach用for访问array的每一项,对每一项调用 fn(array[i],i,array)

查看单个属性

let arr =[111,222,333]
arr[0]                                
通过下标

arr[arr.length] === undefined
arr[-1] === undefined
索引越界

for(let i=0; i<=arr.length; i++){
    console.log(arr[i].tostring())
}
报错:Cannot read prototype'tpString' of undefined (这条报错意味着索引越界)  
意思是你读取的undefined的toString 属性 不是toString 是undefined

x.toString()
其中x如果是undefined ,就报这个错

arr.indexOf(item)
存在返回索引,否则返回-1,有就返回对应的下标,没有就返回-1

使用条件查找元素

arr.find(item => item%2===0)             
找到第一个偶数,find只要有1次返回了非false值就停止,返回这个元素,只返回找到的第一个

arr.findIndex(item => item%2 ===0)
使用条件查找元素的索引,找到第一个偶数的索引,找下标

增加数组中的元素

在尾部加元素
arr.push(newItem)            修改arr,返回新长度
arr.push(item1,item2)        修改arr,返回新长度

在头部加元素
arr.unshift(newItem)         修改arr,返回新长度
arr.unshift(item1,item2)     修改arr,返回新长度

在中间加元素
arr.splice(index,0,'x')      在index处插入'x'
arr.splice(index,0,'x','y')  在index处插入'x','y'   

修改数组中元素

修改
arr[9]=666
arr.splice(9,1,666)

反转顺序(修改原数组)
arr.reverse()

把字符串 var s='abcde'变成'edcba'
s.split('')                       变成数组
s.split('').revese()              反转顺序
s.split('').revese().join('')     合成字符串

自定义顺序(自动改成从小到大排列)
arr.sort()

arr.sort((a,b)=>a-b)
arr.sort((a,b) =>{a-b})
如果a>b,会返回一个正数,a大
如果a=b,会返回0,       相等
如果a<b,会返回一个负数,a小

数组变换

map,    对每一项调用cook,把它的返回值放到数组里
filter, 符合条件的元素调用函数,把返回值放到数组里
reduce, 把每一项都给这个函数,得到最后的值,都返回新数组,不改变原数组

map   n变n     一一映射
arr.map(item=>item*item)   
把数组里面的变成对应的平方

filter   n变少
arr.filter(item => item%2===0) 
对arr进行减少操作,是偶数留下,奇数不要

reduce  n变1  
arr.reduce((sun,item)=>{return sun+item},0)
0是初始值,可以变成[]等任意的定义;reduce初始值为0,把每次的值加起来,得到最后的值

例:求arr=[1,2,3,4,5]的平方
arr.reduce((result,item)=>{return result.concat(item*item)},[])
            表示当前数据       把item和result连成新数组     []初始值是一个空数组
这个数据每次把当前数据的数字做一个数组,把新的数字当做一个数组合起来,返回给上一次

把偶数放进去
let arr=[1,2,3,4,5,6]
arr.reduce((result,item)=>
    result.concat(item%2===1 ? []:item),[])

或者
arr.reduce((result,item)=>{
    if(item%2 ===1) {
    return result
}else{
    return result.concat(item)
}
},[])

数据交换

let arr = [
    {名称:'动物' , id:1 , parent: null},
    {名称:'狗' , id:2 , parent: 1},
    {名称:'猫' , id:3 , parent: 2}
]

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

代码如下:
arr.reduce((result,item) => {
  if(item.parent === null){
    result.id = item.id
    result['名称'] = item['名称']
  }else{
    result.children.push(item)
    delete item.parent
    item.children = null
  }
  return result
},{id: null, children: []})

详细资料点击:JavaScript 数组