1. for
使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显。
代码块当中写入return会报错。
// 求和
let arr = [2, 3, 4, 5],
numbers = 0;
for(let i = 0, len = arr.length; i < len; i++){
numbers += arr[i]
}
console.log(numbers);
// 数组去重
let arr = [2, 3, 5, 6, 3, 5],
newArr = [];
for(let i = 0, len = arr.length; i < len; i++){
if(!~newArr.indexOf(arr[i])){
newArr.push(arr[i]);
}
}
console.log(newArr);
2. foreach
没有返回值,return无效,不支持break 和 continue, 遍历的过程当中索引不变。
let arr = [2, 3, 4, 5];
arr.foreach((curValue, index, self) => {
})
删除自身
forEach因为index索引无法重置,对于删除自身数组元素比较困难,当时filter是比较好的方案
let arr = [1, 2, 1, 1];
arr.slice().reverse().forEach(function (item, index, arr1) {
if (item === 1) {
arr.splice(arr1.length - 1 - index, 1);
}
});
3. map
有返回值,支持return,不支持break 和 continue,遍历的过程当中索引不变。
直接return的返回值,会重新拷贝当前数组,
以新的结果返回。
arr.map((curValue, index, self) => {
})
// 回调函数的传参和foreach一致
map 和 foreach的区别
foreach的返回值无效, 返回undefined,所以只能直接修改本身Array。
map有返回值,而返回值相当于拷贝的结果返回。
4. for of 和 for in
可以正确响应break、continue和return语句
// for of
for(var value of arr){
}
for(var key in arr){
}
注意
使用for in 会遍历对象的所有可枚举属性,包括原型的方法和属性
综上所述, for in 更适合用于遍历对象
Array.prototype.methoud = ()=>{
console.log(this.length);
}
var arr = ['a', 'b', 'c'];
for(var key in arr){
console.log(arr[key]);
}
5. filter 过滤
创建一个新的数组,新数组检查是否符合条件的所有元素
注意: 不会对空数组进行检测, 也不会改变原始数组
Array.filter((curValue, index, arr) => {
}, thisValue)
数组去重
let arr = [2, 3, 5, 6, 3, 5],
newArr = arr.filter((cur, index) =>{
return arr.indexOf(cur) === index;
})
console.log(newArr);
条件筛选
let arr = [
{
value: 100,
done: true
},
{
value: 90,
done: false
},
{
value: 60,
done: true
},
{
value: 80,
done: true
}
]
let newArr = arr.filter((cur) =>{
return cur.value >= 80 && cur.done;
})
6. some 和 every
some 函数对任一项返回true,相当于||,
some一直在找符合条件的值,一旦找到,则不会继续迭代下去。
every 函数对每一项都是true,才会返回true,相当于&&,
every从迭代开始,一旦有一个不符合条件,则不会继续迭代下去。
let arr = [2, 3, 4, 5];
let resultSome = arr.some((cur, index, self) =>{
return cur > 4;
})
let resultEvery = arr.every((cur, index, self) = >{
return cur >= 2;
})
7. reduce
返回累计的结果
// accumulator 累计器
Array.reduce(function(accumulator, curValue, index, self){
}, [initValue])
initValue的设置相当于以什么样的形式第一次进入accumulator,
如果不设置,acc会相当于第一个元素的值,cur的值会是第二个元素,相反设置的话,acc是设置后的值,cur是第一个元素;
而并非索引
求和
let arr = [2, 3, 4, 5];
arr.reduce((acc, cur) => {
return acc + cur;
}, 0)
// 报错,"TypeError: Reduce of empty array with no initial value"
// 数组求乘
arr.reduce((acc, cur) => {
acc.push(cur * 2);
return acc;
}, [])
如果是空数组会报错,因为initValue没有设置;
如果数组只有一个元素,会被直接返回,而不执行回调方法;
所以一般来说我们提供初始值通常更安全
设置成对象
let arr = [2, 3, 4, 5];
arr.reduce((acc, cur) => {
acc.count = acc.count + cur;
return acc;
}, {count: 0})
去重
let arr = [2, 3, 5, 6, 3, 5];
arr.reduce((acc, cur) => {
if(!acc.includes(cur)){
acc.push(cur);
}
return acc;
}, [])
扁平化
let arr = [1, 2, [3, 4], [5, [5, 6]]];
var flatten = arr => {
return arr.reduce((prev, cur) => {
return prev.concat(Array.isArray(cur) ? flatten(cur) : cur)
}, [])
}
flatten(arr);