数组对象
- JS中没有真正的数组,只是用对象模拟一个数组。在JS中数组是一种特殊的对象。
- JS数组的特色
- 数组的元素数据类型可以是不同的。
- 数组内部,元素的内存存储是随机存储的(而不是连续的)。
- index不是数字下标,而是通过字符串下标。这也意味着数组可以有任何key。
新建数组
var arr = [1, 2, 3]
var arr = new Array(1, 2, 3)
var arr = new Array(3)
转化成数组
var arr = '1,2,3'.split(',')
var arr = '123'.split('')
Array.from('123')
伪数组
let divList = document.querySelectorAll('div')
divList.__proto__ === Array.prototype
let divArray = Array.from(divList)
divArray.__proto__ === Array.prototype
- 伪数组:没有数组共有属性的“数组”。
- 伪数组的原型链中没有数组的原型。
- 伪数组的原型直接指向了Object.prototype。
- 伪数组也没有push()、pop()这类数组对象的共有属性。
- 伪数组可以通过Array.from()方法转化为数组。
合并数组
截取数组
- 利用slice()方法,截取一个数组的一部分。
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let arr2 = arr1.slice(2)
arr.slice(start,end),start表示从第几位开始截取,end表示到第几位结束截取。
- 注意
数组的增删改查
增加元素
在头部增加元素:unshift()
arr.unshift(newItem)
arr.unshift(item1, item2)
在尾部增加元素:push()
arr.push(newItem)
arr.push(item1, item2)
在中间增加元素:splice()
arr.splice(index, 0, 'x')
arr.splice(index, 0, 'x', 'y')
(index, 0, 'x')
- index为插入元素的位置。
- 0表示不删除元素。
- 'x'表示插入字符串'x'。
- splice()的返回值为删除的元素的数组,但在增加元素时,没有删除的元素,因此返回值为一个空的数组。
删除元素
- 使用delete关键字
let arr = ['a', 'b', 'c']
delete arr['0']
arr
- 修改数组的.length,可能会删除数组元素。
let arr = ['a', 'b', 'c']
arr.length = '2'
arr
删除头部的元素:shift()
let arr = ['a', 'b', 'c']
arr.shift()
arr
删除尾部元素:pop()
let arr = ['a', 'b', 'c']
arr.pop()
arr
删除指定元素:splice()
let arr = [1, 2, 3, 4, 5, 6]
arr.splice(1,3)
arr
- 返回值为删除的元素的数组。
- 语法:
array.splice(start, deleteCount,item)
- start:删除的开始位置。
- deleteCount:可选。表示要删除的元素的个数,若省略则默认删除从start开始的所有元素。
- item:可选,可添加多个。表示在删除的位置添加的新元素。
查看元素
查看所有属性名和属性值
- Object.keys()和Object.values()
let arr = [1, 2, 3, 4, 5, 6]
arr.x = 'x'
Object.keys(arr)
Object.values(arr)
- for in
let arr = [1, 2, 3, 4, 5, 6]
arr.x = 'x'
for(i in arr){
console.log(i)
}
- 这两种方法会把非数字的下标一起打印。
查看所有数字属性名和值
- 直接使用for循环
let arr = [1, 2, 3, 4, 5, 6]
for(let i = 0; i < arr.length; i++){
console.log(`${i}:${arr[i]}`)
}
- 使用Array().prototype自带的forEach()/map()函数:
let arr = [1, 2, 3, 4, 5, 6]
arr.forEach(function(item, index){
console.log(`${index}:${item}`)
})
- 注意
- for是一个关键字,forEach()是一个普通函数,后者不适用于break。forEach()一旦开始,就必须要全部循环完。
- for后面的花括号代表的是块级作用域,而forEach()后面的花括号代表的是函数作用域。
查看单个属性
- 用下标调用
let arr = [1, 2, 3, 4, 5, 6]
arr[0]
- 查看元素是否在数组里面:indexOf()
arr.indexOf(item)
- 使用条件查找元素,返回元素:find()
let arr = [1, 2, 3, 4, 5, 6]
arr.find(item => item %2 ===0)
arr.find(function(item){
return x % 5 === 0
})
- 它的返回值为元素。
- 只会找到第一个符合条件的元素。
- 使用条件查找元素,返回下标:findIndex()
修改元素
- 直接利用下标来修改。
- 反转顺序
arr.reverse()
- 自定义排列
arr.sort(function(a, b){
return a-b
})
- JS默认情况下,数值小的理应排在前面(顺序排列)。
- 顺序排列:
function(a, b){return a - b}
- 逆序排列:
function(a, b){return b - a}
- 用sort()来排列非数值型的元素:
let arr = [
{name:'小明', score:90},
{name:'小红', score:70},
{name:'小黄', score:80}
]
arr.sort((a, b) => b.score - a.score)
数组变换
map()
- n变n
arr.map(fn())
- 把数字变成星期:
let arr = [0,1,2,2,3,3,3,4,4,4,4,6]
let arr2 = arr.map(item => {
switch(item){
case 0:
return '周日'
case 1:
return '周一'
case 2:
return '周二'
case 3:
return '周三'
case 4:
return '周四'
case 5:
return '周五'
case 6:
return '周六'
}
})
console.log(arr2)
filter()
- n变少
arr.filter(fn())
- 找出所有大于 60 分的成绩:
let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
scores.filter(score => score >=60)
reduce()
- n变1
arr.reduce(fn(result, item),0)
- arr为原数组。
- fn()为变换规则,它最后一次的输出值即为reduce()的最终结果。
- result为结果。每一次fn()的return结果都会赋值给result。
- item为arr中每一项。
- 0为result的初始值。
- 算出所有奇数之和:
let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
scores.reduce((sum, item) => item % 2 !== 0 ? sum + item: sum, 0)
- reduce()的结果可以不是“1”,而可以是多个结果——数组。
- 利用reduce()找出所有大于 60 分的成绩:
let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
scores.reduce((arr, item) => item >= 60? arr.concat(item): arr, [])
拓展
深拷贝和浅拷贝
- 深拷贝:拷贝时,在内存中开辟一个新的空间,并在该空间内复制一份拷贝的对象。
- 浅拷贝:拷贝时,只是复制一份引用对象的地址。
稀疏数组
返回值
- 以
arr[0]为例。
- arr之所以能作为数组第一个数,并对它进行操作,本质原因是:
arr[0]是arr的一个下标为1的属性,能够被直接调用。