数组
- JS数组不是典型的数组 典型的数组(如C语言中的数组):
- 元素的数据类型相同
- 使用连续的内存存储
- 通过数字下标获取元素 JS中的数组:
- 元素的数据类型可以不同
- 内存不一定是连续的(对象是随机存储的)
- 不能通过数字下标,而是通过字符串下标
- 数组可以有任何key,如
let arr = [1,2,3] arr['xxx'] = 1
JS的数组实际上是对象,只不过key值是'0','1',且每一个数组在创建后自带length属性,且该属性会自动更新。JS的数组是用key和value来模拟的。
创建一个数组
-
新建
let arr = [1, 2, 3] //简写形式,常用 let arr = new Array(1, 2, 3) // 正规写法 let arr = new Array(3) // 当只有一个参数时,设置的时长度 -
转化
let arr = '1,2,3'.spllit(',')// 用逗号分隔字符串,结果为["1", "2", "3"] let arr = '123'.split('') // 用空字符串分隔,结果为["1", "2", "3"] Array.from('123') //尝试转化为数组,可传字符串 Array.from({0:'a', 1:'b', 2:'c', length: 4} //尝试转化为数组,可传对象,但需要包含length属性 -
伪数组
没有数组公用属性(Array.prototype)的数组就是伪数组
- 伪数组的原型链中没有数组的原型
array = {0:'a', 1:'b', 2:'c', length:3} // 看起来很像数组,但时原型链中没有Array.prototype,其__proto__ === Object.prototype - 页面所有div,获得的也是伪数组
需要再通过Array.from()转化为数组let divList = document.querySelectorAll('div')let divArray = Array.from(divList)
- 合并数组
-
使用数组对象的concat方法合并两个数组,得到新的数组,不改变原有数组
let arr1 = [1, 2, 3] let arr2 = [4, 5, 6] arr1.concat(arr2) // 结果为[1, 2, 3, 4, 5, 6],arr1和arr2不变 -
截取数组
slice()方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。tips:JS只提供浅拷贝
let arr = [1, 2, 3, 4, 5, 6] arr.slice(1) //从第二个元素开始截取,结果为[2, 3, 4, 5, 6] arr.slice(0) //从第一个元素开始截取,等同于复制该数组,注意JS只提供浅拷贝。
删除元素
-
(不推荐) 使用和对象的delete方法,对应下标的属性值变为empty,数组的长度不变。这类数组中的元素间存在空隙的称为稀疏数组。
let arr = [1, 2, 3] delete arr['0'] //输出为[empty, 2, 3],长度不变 -
(不推荐) 修改length,会将键值对调整至与length向匹配的状态,即将length变小,原有的超出范围的键值对将会被删除。
-
删除头部的元素:arr.shift()
let arr = [1, 2, 3] arr.shift() //返回[2, 3] -
删除尾部元素:arr.pop()
let arr = [1, 2, 3] arr.pop() //返回[1, 2] -
删除中间元素:arr.splice() -- 功能强大
通过删除或替换现有元素或者原地添加新的元素来修改数组,可以使用此方法实现以上的删除方法。
let arr = [1, 2, 3, 4, 5, 6, 7, 8] arr.splice(2, 1) // 指定修改的开始位置为2(从0计数),删除数量为1,返回[1, 2, 4, 5, 6, 7, 8] arr.splice(2, 2) // 指定修改的开始位置为2(从0计数),删除数量为1,返回[1, 2, 6, 7, 8] //添加 let arr2 = [1, 2, 3, 4, 5, 6, 7, 8] arr2.splice(3, 1, 'x') //指定修改的开始位置为2(从0计数),删除数量为1,同时添加1个值'x', 返回[1, 2, 3, 'x', 5, 6, 7, 8] let arr3 = [1, 2, 3, 4, 5, 6, 7, 8] arr3.splice(3, 1, 'x', 'y')//指定修改的开始位置为2(从0计数),删除数量为1,同时添加1个值'x', 返回[1, 2, 3, 'x', 'y', 5, 6, 7, 8]
查看元素
-
使用对象的方法查看所有属性名再遍历
trap:Object.keys(arr)会返回所有属性名,但这并非我们所希望的结果。(从Object角度理解而非Array)
let arr = [1, 2, 3, 4, 5] arr.x = 'x' Object.keys(arr) // 返回["0", "1", "2", "3", "4", "x"] Object.values(ar) // 返回[1, 2, 3, 4, 5, "x"] -
结合for循环与length属性进行遍历
for(let i = 0; i < arr.length; i++){ console.log(`${i} : ${arr[i]}`) } -
使用forEach/map等原型上的函数
此处使用了回调。(回调的东西之后再补补)
forEach方法遍历整个数组,每一次都调用所传函数。函数可接收三个参数,item,index,array。
arr.forEach(function(item, index){ console.log(`${index} : ${item}`方法2与方法3的区别:
- for循环中可以使用break,continue,较forEach方法而言,功能更加强大
- for为关键字,内部为块级作用域;forEach为函数,内部为函数作用域。(作用域的东西之后再补补)
-
查看单个属性
- 与对象同
let arr = [1, 2, 3, 4, 5] arr[0] // 返回1 //索引越界的情况 arr[arr.length] === undefined arr[-1] === undefined
- 查看某个元素是否在数组中
- 用for循环遍历(不推荐)
- arr.indexOf(x):返回x在数组中的下标,若不存在则返回-1
arr.find(fn):获取符合条件的数,返回第一个使该函数返回true的值,只会返回第一个值,无下标信息
arr.findIndex(fn):获取符合条件的数的索引,返回第一个使该函数返回true的值的索引,只会返回第一个值,无下标信息
//使用arr.indexOf(x)获取下标 let arr = [5, 4, 3, 2, 1] arr.indexOf(5) // arr.indexOf(x)返回x在数组中的下标,若不存在则返回-1 //使用arr.find(fn) arr.find((x) => x%5 === 0) //返回第一个为5的倍数的值 //使用arr.findIndex(fn) arr.find((x) => x%2 === 0) //返回第一个偶数的索引
增加元素
- (不推荐) 直接通过下标增加元素
let arr=[1,2,3,4,5] arr[100] = 1 //arr的length同样修改了,中间其他未赋值的为empty,稀疏数组 - 在尾部增加元素
let arr = [1,2,3,4,5] arr.push(6, 7) // 返回[1,2,3,4,5,6,7] - 在头部增加元素
let arr = [1,2,3,4,5] arr.unshift(6, 7) // 返回[6,7,1,2,3,4,5] - 在中间添加
使用arr.splice()
let arr = [1,2,3,4,5] arr.splice(3, 0, 'x', 'y') // 返回[1, 2, 'x', 'y', 3, 4, 5]
修改元素
-
直接通过下标修改
let arr=[1,2,3,4,5] arr[3]=777 /// 修改下标3数据为777,输出[1, 2, 3, 777, 5] -
反转顺序
arr.reverse(),修改原数组
let arr=[1,2,3,4,5] arr.reverse() //反转原数组顺序题目:反转字符串‘abcde’
思路:
- 先将字符串转换为数组对象,
- 然后反转数组元素顺序,
- 最后再转换回字符串
//题目:反转字符串‘abcde’ let s='abcde' s.split('').reverse().join('') //join()方法用于把数组中的所有元素转换一个字符串 -
自定义顺序
使用arr.sort()方法,可传入比较方法(compareFunction)来实现自定义排序。
比较方法compareFunction(a,b):
- 返回的值大于0(一般使用1),b排在a之前。
- 返回的值等于0,a 和 b 的相对位置不变。
- 返回的值小于0(一般使用-1),a排在b之前
换种方式理解一下,假定sort排序方式为从小到大,返回的值大于0,即表示a>b;等于0,即a与b相等;小于0,即表示a<b。
arr.sort(function(a,b){ if(a>b) {return -1} else if(a===b) {return 0} else {return 1} })按分数排序:
let arr = [ {name:'1', score:99}, {name:'2', score:95}, {name:'3', score:100}, ] //简练优化版本 arr.sort((a,b) => a.score - b.score)
数组变换
-
map:n变n(一一对应)
let arr = [1,2,3,4,5] arr.map(item=>item*item)//一一映射,得到新数组[1,4,9,16,25] -
filter:n变少(保留符合要求的)
//题目:把下面数组过滤减少,只保留里面的偶数 let arr=[1,2,3,4,5,6] arr.filter(item=>item % 2 === 0? true : false) //输出[2,4,6] arr.filter(item=>item % 2 === 0) //简写形式 -
reduce:n变1
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。(FromMDN)
reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:
- accumulator 累计器
- currentValue 当前值
- currentIndex 当前索引
- array 数组
题目:把下面数组相加求和
//题目:把下面数组相加求和 let arr=[1,2,3,4,5,6] arr.reduce((sum,item)=>{return sum+item},0) //0代表初始值,每一次都把这一轮结果放到赋值给sum题目:把下面数组每一项变成它的平方,通过reduce实现
//题目:把下面数组每一项变成它的平方,通过reduce实现 let arr=[1,2,3,4,5,6] arr.reduce((resule,item)=>{return result.concat(item*item)},[]) //初始值为空数组,通过concat把上一次结果和这一次结果连成数组题目:把下面数组过滤减少,只保留里面的偶数,通过reduce实现
//题目:把下面数组过滤减少,只保留里面的偶数,通过reduce实现 let arr = [1, 2, 3, 4, 5, 6]; arr.reduce((resule, item) => { if (item % 2 === 1) { return result; } else { return result.concat(item); } }, []); //简写形式 arr.reduce((result, item) => result.concat(item % 2 === 1 ? [] : item), []); //每次都要concat,如果是奇数就concat一个空数组[],如果是偶数就concat当前item