函数
连接有关
concat() 连接成新数组
var arr1 = [1,2,3]
var arr2 = [4,5,6]
var arr3 = arr1.concat(arr2) //注意一定要一个新变量来赋值,并不是直接连接在arr1上
console.log(arr3) // [1,2,3,4,5,6]
结果返回,不会改变原值
join() 连接子项成字符串
var arr1 = [1,2]
var str = arr1.join("-")
console.log(str) // 1-2
结果返回,不改变原值
首尾有关
pop() 删除最后一个元素
var arr1 = [12,13]
var num = arr1.pop() //表示删除后,把被删除的元素赋值
console.log(arr1, num) // [12] 13
返回被删除子项,原值被修改
push() 末尾添加一个元素
var arr1 = [1,2,3]
arr1.push(5) // 注意,push的是子项不是数组
console.log(arr1) // [1,2,3,5]
返回修改后的length,原值被修改
unshift() 头部插入元素
同push()
用法,修改后的length,原值被修改
shift() 删除第一个元素
同pop()
用法,返回被删除子项,原值被修改
顺序有关
reverse() 反转数组
let arr = [1, 2, 3, 4]
let brr = arr.reverse()
console.log(arr, brr); // 都是[4,3,2,1]
返回反转后的结果,原值被修改
sort() 自定义排序
具体还是看掘金的这篇文章:《forEach如何修改原数组和sort排序经典场景》
以下补充:
// 打乱数组顺序
arr.sort((a, b) => (Math.random() > 0.5 ? -1 : 1));
遍历有关
forEach(fn) 普通遍历
arr.forEach(function(a, b, c){ // 函数内第一个参数为元素,第二个参数为下标,第三个为数组本身
// 这里写每一轮遍历后做什么事
})
// forEach除了回调外的第二个参数就是改变this的指向
arr.forEach(function(a, b, c){
console.log(this) //指向xxx
}, xxx}
tips:如果内部return相当于continue,而且不会返回任何值。
无返回
会不会对原值进行修改,之前我有误解,一定要看看这篇文章《forEach如何修改原数组和sort排序经典场景》想改原值还是用下面的map
更好。
执行效率上还是for循环高,因为forEach每次都要初始化一个函数,然后函数还有独立的作用域开销。
map(fn) 映射出新数组
// 括号里的函数时映射的机制
let arr1 = [56,78,88]
let arr2 = arr1.map(item=> item>=60? '及格' : ‘不及格’; )
// 记得要return出去。
//例子:如果要把一个数组里的每个元素的其中一个东西替换元素,成为新数组
let arr1 = [{a:1,b:1},{a:2,b:2}]
let arr2 = arr1.map(item=>item.a )
主要用于要对某个数组的每一项进行改造,有个缺点就是每个元素必定会返回内容,如果不写逻辑就会返回undefined。
返回修改后的数组,原值会不会改变可以参考forEach
filter(fn) 过滤
// 过滤出满足条件的数组
// ()里面写过滤的机制,第一个参数为元素,第二个为下标
let arr = [1,2,3,4,5]
let arr2 = arr.filter((item,i)=>{
return i > 3 // i 为下标 需要什么一定要return
})
console.log(arr2) //[3,5] 记住拿到的结果是数组
//例子: 过滤出数组里的偶数
let arr = [1,2,3,4,5]
let arr = arr.filter(item=>item%2==0)
返回过滤后的新数组,如果都没有满足条件就返回一个[]
,原值会不会改变可以参考forEach
还在别处发现个有趣的用法,过滤没用的子项:
// 过滤空值
const groceries = ['apple', null, 'milk', undefined, 'bread', ''];
const cleanList = groceries.filter(Boolean);
console.log(cleanList);
// 'apple', 'milk', 'bread';
every(fn) 判断数组中的所有元素是否符合条件
// 对数组中每一项运行给定函数,如果该函数的每一项都返回true,则返回true
var arr = [1, 2, 3, 4, 5]
console.log(arr.every((item, index, array) => {
return item > 3
}))// false
注意,当数组为空时,无论什么条件,返回的都是true
返回布尔,原值会不会改变可以参考forEach
some(fn) 判断数组中是否有某个元素符合条件
// 对数组中每一项运行给定函数,如果该函数的有某一项返回true,则返回结果返回true
var arr = [1, 2, 3, 4, 5]
console.log(arr.some((item, index, array) => {
return item > 3
})) // true
返回布尔,原值会不会改变可以参考forEach
,注意了空数组和every不同,是会正常返回false的。
reduce(fn) 把数组里的所有元素处理成一个结果
// 例子:求平均数
let arr = [12, 23, 45, 56, 4, 23]
let result = arr.reduce(function(tmp, item, index){ //自动循环
if(index == arr.length - 1){
return (tmp + item) / arr.length
}else{
return tmp + item //tmp为临时存储,每次循环都把每一个元素加进去
}
})
console.log(result)
// tmp的初始化可以这样写,比如为一个空数组
arr.reduce(function(tmp,item){}, [] )
返回处理的结果,原值会不会改变可以参考forEach
这玩意感觉不如外面自己搞个新变量,也是一样的效果:
let res = 0
arr.forEach(( item, index)=>{
if (index == arr.length - 1) {
res = (res + item) / arr.length
} else {
res += item
}
})
console.log(res);
缺失
slice() 截取范围下标元素
// slice [slaɪs] 单词 切片
arr = arr.slice(0, 6) // 获取0到6的元素
brr = arr.slice(0) // 第二参数不写表示截取到最后
brr = arr.slice(-2) // 从倒数第二个开始截取
brr = arr.slice() // 一维深拷贝
返回新数组,原值不会改变
splice() 设定起始位置添加或删除元素
// splice [splaɪs] 单词 接合
// 参数:
// 1 添加或者删除的索引位置(0 x 1 x 2 x 3...)
// 2 删除多少个元素(不想删就写0)
// 3 后面都是添加的内容
var arr = [1, 2, 3]
var brr = arr.splice(1, 1, 4) // brr = [2] arr = [1, 4, 3] 原值被修改
var brr = arr.splice(1) // 参数只有一个数字,则表示从这个数值的位置开始,把后面的全部删除;arr = [1] brr = [2, 3]
返回删除的元素,原值不会变
同字符串方法
indexOf() 左往右判断元素位置
同字符串的用法,返回结果,原值不变
lastIndexOf() 右往左判断元素位置
同字符串的用法,返回结果,原值不变
toString() 转成字符串
let arr = [1,2,3]
console.log(arr.toString()) // '1,2,3'
返回结果,原值不会改变
ES6新增常用
Array.from(fn) 把伪数组/字符串/遍历器、转换成数组
伪数组例子:
let aLi = document.getElementsByTagName('li');
// console.log(aLi);
for(let i in aLi){
console.log(i);//直接这样循环会把aLi的属性都循环出来,比如下标加上length。
}
for (let i in Array.from(aLi)){
aLi[i].style.color = "red"; //这样转换成数组的形式,就没了其他属性,只剩下标
}
// 如果是es5实现的话:
let newArr = Array.prototype.slice.call(aLi)
字符串例子:
let str = '123'
let arr = Array.from(str) // ['1', '2', '3']
arr = arr.toString() // '123'
遍历器例子:
let map = new Map()
map.set('a', '1')
arr = Array.from(map.values()) // ['1']
copyWithin() 拷贝元素到指定位置替换
在数组的内部去拷贝一些元素放在本数组的指定位置;有三个参数a,b,c,意思是从b下标到c下标(不包含c)的元素拷贝并替换到a下标的元素。
let arr = [1,2,3,4,5,6];
arr.copyWithin(0,3,4);
console.log(arr); // 4,2,3,4,5,6
fill() 单个元素替换内部所有元素
表示用()里的一个数字,去覆盖掉一个数组里的所有元素。
let arr2 = [1,2,3];
arr2.fill(0);
console.log(arr2); // [0, 0, 0]
find(fn) 过滤出满足条件的一个元素
从开头开始逐个查找数组里面的元素,返回第一个符合条件的元素,没有就返回undefined
。
let arr4 = [1,2,3,4,5];
let arrFind = arr4.find(function (v,i,a) { //v表示元素值 i表示下标 a表示数组
// console.log(v,i,a);
return v > 3; //返回元素4
});
console.log(arrFind);
findIndex(fn) 过滤出满足条件的一个下标
从开头开始逐个查找数组里面的元素,返回第一个符合条件的元素下标。没有就返回-1
。
let arr4 = [1,2,3,4,5];
let arrIndex = arr4.findIndex(function (v,i,a) {
return v > 3
})
console.log(arrIndex);
includes() 判断元素是否在数组里
检查元素是否在数组里面,与es5的indexOf()
功能类似,可以比较记忆一下
let arr5 = [1,2,3];
console.log(arr5.includes(4)) //false
Array.of() 数组创建
这个个人认为是为了解决一个原ES5的问题:
let arr = new Array(4)
console.log(arr) // 例如只写4,表示创建一个有4个空元素的数组
用了Array.of()
就能解决问题了
let arr = Array.of(4)
console.log(arr) // [4]
flat() 扁平化元素
主要是用来把数组一维化(不支持IE浏览器):
[1, 2, [3, 4]].flat() // [1, 2, 3, 4] 默认只扁平一层
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5] ,2表示扁平化2层
[1, [2, [3]]].flat(Infinity) // [1, 2, 3],Infinity表示一路扁平到底
注意事项
- 伴随返回的结果一般是浅拷贝对象
这里普及一个概念:纯函数api
满足不修改原值,且返回与原值相同类型的数据就是一个纯函数api,例如concat
类数组
例如我们获取的元素集合、函数入参argument等,如何转成数组:
let arr = Array.from(list)
let arr = Array.prototype.slice.call(list)
let arr = [...list]