- JS没有真正的数组
- 创建一个数组
- 数组中的元素增删改查
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
JS没有真正的数组
JS使用对象模拟数组 |
---|
JS的数组不是典型的数组。
典型的数组:元素的数据类型相同,使用连续的内存存储,通过下标获取元素

JS的数组:元素的数据类型可以不同,内存不一定是连续的(对象是随机存储的),不能通过数字下标,而是通过字符串下标,这意味着数组可以有任何key。
比如:
代码语言:javascript复制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 str = '1,2,3'
str.split(',')
(3) ["1", "2", "3"]
let str2 = '1,2,3,4'.split(',')
str2
(4) ["1", "2", "3", "4"]
let str3 = '123'.split('')
str3
(3) ["1", "2", "3"]

代码语言:javascript复制//通过Array.from将不是数组的元素 变成数组(但是很局限)
Array.from('1234')
(4) ["1", "2", "3", "4"]
Array.from(123)
[]
Array.from(true)
[]
Array.from({name: 'zls'})
[]
Array.from({0:'a',1:'b',2:'c'})
[]
//对象必须有0 1 2 3的下标,然后有length
Array.from({0:'a',1:'b',2:'c',length:3})
(3) ["a", "b", "c"]

伪数组 |
---|
array = [1,2,3,4,5] // new Array(1,2,3,4,5)
(5) [1, 2, 3, 4, 5]
array.__proto__ === Array.prototype
true
array
(5) [1, 2, 3, 4, 5]
0: 1
1: 2
2: 3
3: 4
4: 5
length: 5
__proto__: Array(0)
array2 = {0:'a',1:'b',2:'c',3:'d'}
{0: "a", 1: "b", 2: "c", 3: "d"}
array2.__proto__ === Array.prototype
false

注意: 在伪数组的原型链中,并没有数组的原型,它的原型是对象(Object)的原型
我们使用 document.querySelectorAll('div') 就是一个伪数组
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
</body>
</html>
代码语言:javascript复制let divList = document.querySelectorAll('div')
console.log(divList)

当你使用divList.push(4)
的时候,会发现报错,根本没有办法使用数组的push

如果我们想要他变成数组,就要使用刚才所学 Array.from
let divList = document.querySelectorAll('div')
let divArray = Array.from(divList)
console.log(divArray)

没有数组共用属性的数组,就是伪数组
合并两个数组,会得到新数组 |
---|
//使数组变长(合并)
array1 = [1,2,3]
(3) [1, 2, 3]
array2 = [2,3,4]
(3) [2, 3, 4]
array1.concat(array2)
(6) [1, 2, 3, 2, 3, 4]
array1
(3) [1, 2, 3]
array2
(3) [2, 3, 4]

代码语言:javascript复制// 使数组变短(截取)
array3 = [1,2,3,4,5,6,7,8]
(8) [1, 2, 3, 4, 5, 6, 7, 8]
array4 = array3.slice(2)
(6) [3, 4, 5, 6, 7, 8]
array4
(6) [3, 4, 5, 6, 7, 8]

数组中的元素增删改查
删除元素 |
---|
let arr = ['a','b','c']
delete arr['0']
// 很惊奇的事情发生了,数组的长度不变
let arr = ['a','b','c','d']
arr.length
4
delete arr['0']
true
arr.length
4
arr
(4) [empty, "b", "c", "d"]

只有长度,没有下标的 数组,叫做:稀疏数组
如果修改长度,,,属性名就没有了
代码语言:javascript复制let arr = ['a','b','c','d']
arr.length = 2
2
arr
(2) ["a", "b"]
注意: JS千万不要改length
所以,删除数组使用shift
或者 pop
let array = [1,2,3,4,5]
//从左边删除
array.shift()
1
array
(4) [2, 3, 4, 5]
array.shift()
2
array
(3) [3, 4, 5]
//从后面删除
array.pop()
5
array
(2) [3, 4]
//从中间删除,从下标为2的地方删除一个元素
let array1 = [1,2,3,4,5]
array1.splice(2,1)
[3]
array1
(4) [1, 2, 4, 5]
//在删除的同时还可以增加
let array2 = [1,2,3,4,5]
array2.splice(2,1,666)
[3]
array2
(5) [1, 2, 666, 4, 5]
array2.splice(2,1,777,888,999)
[666]
array2
(7) [1, 2, 777, 888, 999, 4, 5]

遍历元素 |
---|
let arr = [1,2,3,4,5]
arr.x = 'x'
"x"
Object.keys(arr)
(6) ["0", "1", "2", "3", "4", "x"]
//查看数组的value,下面几种方法都是有问题的
arr
(5) [1, 2, 3, 4, 5, x: "x"]
// 为什么带个x?
Object.values(arr)
(6) [1, 2, 3, 4, 5, "x"]
// 为什么带个x?
for(let i in arr){
console.log(i)
}
VM617:2 0
VM617:2 1
VM617:2 2
VM617:2 3
VM617:2 4
VM617:2 x
//正确方式,看到所有的key
for(let i=0;i<arr.length;i ){
console.log(i)
}
0
1
2
3
4
//看到所有的key和value
for(let i=0;i<arr.length;i ){
console.log(i,arr[i])
}
0 1
1 2
2 3
3 4
4 5
for(let i=0;i<arr.length;i ){
console.log(`${i}:${arr[i]}`)
}
0:1
1:2
2:3
3:4
4:5
//使用forEach函数遍历数组
arr.forEach( function(xxx){
console.log(xxx)
} )
1
2
3
4
5
arr.forEach( function(xxx,yyy){
console.log(xxx,yyy)
} )
1 0
2 1
3 2
4 3
5 4
arr.forEach( function(xxx,yyy){
console.log(`${xxx}:${yyy}`)
} )
1:0
2:1
3:2
4:3
5:4
//使用map函数遍历数组
arr.map( function(xxx,yyy){
console.log(xxx,yyy)
} )
1 0
2 1
3 2
4 3
5 4
查看单个元素 |
---|
let arr = [1,2,3,4,5,6,7]
arr[1]
2
arr[0]
1
//越界索引
for(let i=0;i<=arr.length;i ){
console.log(arr[i].toString())
}
1
2
3
4
5
6
7
Uncaught TypeError: Cannot read property 'toString' of undefined
at <anonymous>:2:24

读取了undefined的toString属性
代码语言:javascript复制//查找某个元素是否在数组中
let arr = [1,23,45,33,16,66,88]
arr.indexOf(1)
0
arr.indexOf(88)
6
//找某个元素是不是偶数,或者是5的倍数
let arr = [12,23,12,222,45,16,100]
arr.find((x)=> x%5 === 0)
45
arr.find(function(x){ return x%5 === 0 })
45
arr.find(function(x){ return x%2 === 0 })
12
//找到下标
arr.findIndex(function(x){ return x%2 === 0 })
0
给数组增加元素 |
---|
错误添加元素方式
代码语言:javascript复制//从下面我们会发现,如果突然写个很大的下标,数组长度会变成101,空元素有很多,这样就变成了一个稀疏数组
let arr2 = [1,2,3,4,5,7,8,9,4,5,6,7]
arr2[12] = 22
22
arr2
(13) [1, 2, 3, 4, 5, 7, 8, 9, 4, 5, 6, 7, 22]
arr2.length
13
arr2[13] = 33
33
arr2
(14) [1, 2, 3, 4, 5, 7, 8, 9, 4, 5, 6, 7, 22, 33]
arr2.length
14
arr2[100] = 666
666
arr2
(101) [1, 2, 3, 4, 5, 7, 8, 9, 4, 5, 6, 7, 22, 33, empty × 86, 666]
arr2.length
101

推荐方式
代码语言:javascript复制//push在最后面添加元素
let arr = [1,2,3,4,5,6]
arr.push(7)
7
arr
(7) [1, 2, 3, 4, 5, 6, 7]
arr.push('a','b','c')
10
arr
(10) [1, 2, 3, 4, 5, 6, 7, "a", "b", "c"]
//unshift在最前面添加元素
arr.unshift(0)
11
arr
(11) [0, 1, 2, 3, 4, 5, 6, 7, "a", "b", "c"]
arr.unshift('x','y','z')
14
arr
(14) ["x", "y", "z", 0, 1, 2, 3, 4, 5, 6, 7, "a", "b", "c"]
//在指定位置添加
arr
(14) ["x", "y", "z", 0, 1, 2, 3, 4, 5, 6, 7, "a", "b", "c"]
arr.splice(9,0,6.5) //在下标是9的位置,删除0个元素,添加一个元素为6.5
[]
arr
(15) ["x", "y", "z", 0, 1, 2, 3, 4, 5, 6.5, 6, 7, "a", "b", "c"]

修改数组元素 |
---|
//方法一:还是使用splice
arr.splice(9,1,6.666)
[6.5]
arr
(15) ["x", "y", "z", 0, 1, 2, 3, 4, 5, 6.666, 6, 7, "a", "b", "c"]
//方法二:直接修改
arr[9] = 8.888
8.888
arr
(15) ["x", "y", "z", 0, 1, 2, 3, 4, 5, 8.888, 6, 7, "a", "b", "c"]
//数组反转
arr.reverse()
(15) ["c", "b", "a", 7, 6, 8.888, 5, 4, 3, 2, 1, 0, "z", "y", "x"]
arr
(15) ["c", "b", "a", 7, 6, 8.888, 5, 4, 3, 2, 1, 0, "z", "y", "x"]
//面试题,如何把字符串反转?
let str = 'abcd'
str.split('')
(4) ["a", "b", "c", "d"]
str.split('').reverse()
(4) ["d", "c", "b", "a"]
str.split('').reverse().join('')
"dcba"
//顺序是乱的数组,变成有序数组
let arr = [5,2,1,3,4]
arr.sort()
(5) [1, 2, 3, 4, 5]
arr
(5) [1, 2, 3, 4, 5]
arr.sort(function(a,b){
if(a>b){
return 1
}else if(a===b){
return 0
}else{
return -1
}
})
(5) [1, 2, 3, 4, 5]
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]
//如果是下面的数组,JS根本就不知道,按照什么排序
let stu = [
{name: 'zhang3',score: 99},{name: 'li4',score: 95},{name: 'wang5',score: 100}]
stu.sort()
(3) [{…}, {…}, {…}]
0: {name: "zhang3", score: 99}
1: {name: "li4", score: 95}
2: {name: "wang5", score: 100}
//所以我们需要通过sort的函数,来告诉JS用score排序
stu.sort(function(a,b){
if(a.score > b.score){
return 1
}else if(a.score === b.score){
return 0
}else{
return -1
}
})
(3) [{…}, {…}, {…}]
0: {name: "li4", score: 95}
1: {name: "zhang3", score: 99}
2: {name: "wang5", score: 100}
//简便写法
stu.sort((a,b) => a.score - b.score)
(3) [{…}, {…}, {…}]
0: {name: "li4", score: 95}
1: {name: "zhang3", score: 99}
2: {name: "wang5", score: 100}
数组变换 |
---|

代码语言:javascript复制//map: n变n
let arr = [1,2,3,4,5,6]
arr.map(item => item * item)
(6) [1, 4, 9, 16, 25, 36]
//filter: n变少
arr
(6) [1, 2, 3, 4, 5, 6]
arr.filter(item => item%2 === 0 ?true :false)
(3) [2, 4, 6]
arr.filter(item => item%2 === 0)
(3) [2, 4, 6]
//reduce:n变1,抢劫...
for(let i=0;i<arr.length;i ){
//sum = sum arr[i] 可以简写
sum = arr[i]
}
21
arr.reduce((sum,item)=>{return sum item},0)
21
//使用reduce实现,map的例子
arr.reduce((result,item) => {return result.concat(item * item)},[])
(6) [1, 4, 9, 16, 25, 36]
//使用reduce实现,filter的例子
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),[])
(3) [2, 4, 6]
//有经验的前端简化代码
arr.reduce((result,item) => result.concat(item % 2 === 1 ?[] :item),[])
(3) [2, 4, 6]
面试题:数据变换 |
---|
//将下列数组
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}
]
}

代码语言:javascript复制arr.reduce((result,item) => {
result[item.id] = item
return result
},{})
{1: {…}, 2: {…}, 3: {…}}
1: {2: {…}, 名称: "动物", id: 1, parent: null}
2: {3: {…}, 名称: "狗", id: 2, parent: 1}
3: {名称: "猫", id: 3, parent: 1}
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: []})