数组对象
一种特殊的对象。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)
转化
- let arr = '1,2,3'.split(',')
- let arr = '123'.split('')
- Array.from('123')
伪数组
- let divList = document.querySelectorAll('div')
- 伪数组的原型链
没有数组共用属性的 【数组】就是伪数组。
合并两个数组,得到新数组
- arr1.concat(arr2)
截取一个数组的一部分
- arr1.slice(1) //从第二个元素开始
- arr1.slice(0) //全部截取
- 注意,JS只提供浅拷贝
数组元素增删改查
删元素
跟对象一样
- let arr = ['a','b','c']
- delete arr['0']
- arr //[empty,'b','c'] , 数组的长度并没有变,bug的稀疏数组
如果直接改length可以删元素
- let arr = [1,2,3,4,5]
- arr.length = 1 //JS是可以通过这种方式改length的
- 重要:不要随便改length
推荐使用删除元素的方式
删除头部的元素
- arr.shift() //arr被修改,并返回被删除元素
删除尾部的元素
- arr.pop //arr被修改,并返回被删除元素
删除中间的元素
- 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'
- Object.keys(arr)
- for(let key in arr){console.log(
${key}:${arr[key]}
)}
查看数字(字符串)属性
for(let i = 0; i < arr.length; i++){
console.log(`${i}: ${arr[i]}`)
}
要自己让i从0增长到length-1
arr.forEach(function(item,index){
console.log(`${index}: ${item}`)
})
也可以用forEach / map 等原型上的函数
forEach 写法
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)
- 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 property 'toString' of undefined
查找某个元素是否在数组里面
- arr.indexOf(item) //存在返回索引,不存在返回-1
使用条件查找元素
- arr.find(item => item % 2 === 0) //找第一个偶数
使用条件查找元素的索引
- 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.aplice(index,0,'x') //在index处插入'x'
- arr.splice(index,0,'x','y')
修改数组中的元素
反转顺序
- arr.reverse() //修改原数组
自定义顺序
- arr.sort() //默认从小到大
让数字大的在前面,从大到小
arr.sort( function(a,b) {
if(a>b){
return -1
}else if(a===b){
return 0
}else{
return 1
}
} )
对象的排序方式
let arr = [
{name: '小明',score: 99},{name:'小红',score: 95},{name:'大黄',score: 100}
]
arr.sort(function(a,b){
if(a.score > b.score){return 1}
else if(a.score == b.score){return 0}
else{return -1}
})
arr.sort((a,b) => a.score - b.score) //上面方式的简写,a>b返回正数,a=b返回0,a<b返回负数,js就知道谁大了。
数组变换
map:n变n、filter:n变少、reduce:n变1
面试题
数据转换
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:[]})
把数字变成星期
let arr = [0,1,2,2,3,3,3,4,4,4,4,6]
let arr2 = arr.map((i)=>{
const hash = {0:'周日',1:'周一',2:'周二',3:'周三',4:'周四',5:'周五',6:'周六'}
return hash[i]
})
console.log(arr2) // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']
找出所有大于60分的成绩
let scores = [95, 91, 59, 55, 42, 82, 72, 85, 67, 66, 55, 91]
let scores2 = scores.filter(item => item > 60)
console.log(scores2) // [95,91,82,72,85,67,66, 91]
算出所有奇数之和
let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let sum = scores.reduce((sum, n)=>{
return n%2===0?sum:sum+n
},0)
console.log(sum) // 奇数之和:598