JS 数组

122 阅读3分钟

数组对象,一种特殊的对象

JS其实没有真正的数组,只是用对象模拟数组

JS的数组不是典型数组

典型的数组:

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

创建一个数组

  1. 新建
let arr = [1,2,3]
let arr = new Array(1,2,3) 
let arr = new Array(3)
  1. 转化
let arr = '1,2,3'.split(',') 
let arr = '123'.split(")
Array.from('123') // 把伪数组变成数组
  1. 伪数组
let divList = document.querySelectorAll('div')
{0: 'a', 1: 'b', 2:'c', 3: 'd', length: 4}

伪数组的原型链中并没有数组的原型

  1. 合并两个数组,得到新数组
arrl.concat(arr2)
  1. 截取一个数组的一部分
arr1.slice(1) //从第二个元素开始
arrl.slice(0) //全部截取

注意, JS只提供浅拷贝

删元素

  1. 跟对象一样
let arr = ['a' , 'b', 'c'] 
delete arr['0'] 
arr      // [empty, 'b', 'c']

神奇,数组的长度并没有变,这样得到的数组叫稀疏数组

  1. 如果直接改length可以删元素吗
let arr = [1,2,3,4,5]
arr.length = 1
arr     // [1]

重要:不要随便改length

  1. 上面两种方法都不推荐,推荐使用以下方法:

1、删除头部的元素:arr.shift() arr被修改,并返回被删元素

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

3、删除中间的元素:

  • arr.splice(index, 1) 删除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'

使用以下两种方法,都会得到key: x

Object.keys(arr)    
for(let key in arr){console.log(`${key}:${arr[key]}`)}

image.png

使用for循环

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

你要让 i 自己从 0 增长到 length-1

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

arr.forEach(function(item, index){
  console.log(`${index}: ${item}`)
}

// 模拟实现forEach
function forEach(array, fn){
  for(let i = 0; i < array.length; i++ ){
    fn(array[i], i, array)
  }
}
forEach(arr, function(item, index){
  console.log(`${index}: ${item}`)
})

for循环和forEach的区别:

  1. for循环可以break和continue,而forEach不支持
  2. for是个关键字,for循环是个块级作用域,forEach是个函数,函数作用域

查看单个属性

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 property 'toString' ofundefined

  1. 查找某个元素是否在数组里 arr.indexOf(item) // 存在返回索引,否则返回-1

  2. 使用条件查找元素 arr.find(item => item % 2--=0) //找第一个偶数

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

增加数组中的元素

  1. 在尾部加元素 arr.push(newltem) //修改arr,返回新长度

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

  1. 在头部加元素 arr.unshift(newltem) //修改arr,返回新长度

arr.unshift(item l, item2) //修改arr,返回新长度

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

arr.splice(index, 0,'x','y')

修改数组中的元素

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

例:反转字符串'abcde'

'abcde'.split('').reverse().join('')  // 'edcba'
  1. 自定义顺序:
arr.sort((a,b)-> a-b)  // 从小到大
arr.sort((a,b)-> b-a)  // 从大到小

数组变换

image.png

  1. map:n变n arr.map((item)=>item*item)

  2. filter:n变少 arr.filter((item)=>item < 10)

  3. reduce:n变1 arr.reduce((sum, item)=> sum + item, 0)

image.png

面试题数据变换

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}
  ]
}
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: []})