不废话,直接上正题。
for循环
for循环是最基本的循环,这里只介绍它的注意点。
// 使用 break 语句来终止循环
let arr = [1,2,3,4,5];
for (i = 0; i < arr.length; i++) {
if (arr[i] == 3) {
break;
}
console.log(arr[i]); // 1, 2
}
// continue 语句可以用来继续执行(跳过代码块的剩余部分并进入下一循环)for。
let arr = [1,2,3,4,5];
for (i = 0; i < arr.length; i++) {
if (arr[i] == 3) {
continue;
}
console.log(arr[i]); // 1, 2, 4, 5
}
forEach
让数组中的每一项都做一件事,如果不做特殊处理,一般情况下,不能中止或跳出 forEach 循环(使用break会报错,return false 也无效)。如果需要中途跳出循环,建议直接用for语句好了。
let arr = [1,2,3,4,5];
arr.forEach((item,index)=> {
console.log(item);
})
// 1,2,3,4,5
// for语句可以跳出循环
var arr = [1,2,3,4,5];
for(var i = 0; i < arr.length; i++){
if(i > 2){
break;
}
console.log(i);
}
// 0 1 2
map
让数组通过某种计算产生一个新数组
let arr = [1,2,3,4,5];
let newArray = arr.map((item,index)=> {
return item * 2
});
newArray // [2, 4, 6, 8, 10]
arr // [1,2,3,4,5]
map() 与 forEach() 语法一致,能用forEach()
做到的,map()
同样可以,但是存在区别。
区别:
forEach()返回值是undefined,不可以链式调用;
map()返回一个新数组,原数组不会改变.
reduce
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
initialValue:传递给函数的初始值;
让数组中的前项和后项做某种计算,并累计最终值,callbackFunction 包含4个参数,先解释下它们的意思:
prev:第一项的值或者上一次叠加的结果值
cur: 当前会参与叠加的项
index: 当前索引
arr: 数组本身
let arr = [1,2,3,4,5];
let result = arr.reduce((prev, cur, index, arr)=> {
console.log(prev);
return prev + cur;
});
// 结果:
// 1 2
// 3 3
// 6 4
// 10 5
console.log(arr); // [1,2,3,4,5]
console.log(res); // 15
// 此时,初始值默认为数组的 [0],如果想自定义初始值,那可以给reduce添加第二个参数(initialValue),如下
let result = arr.reduce((prev, cur, index, arr)=> {
return prev + cur;
}, -5);
// -5 1
// -4 2
// -2 3
// 1 4
// 5 5
// 如果是累加,一定要注意 initialValue 的类型,如果设置成了字符串,根据 “两者相加,值类型与第一个加数相同”,那么结果就是一个字符串。
场景应用:
1、展平数组
const twoDArr = [ [1,2], [3,4], [5,6], [7,8] , [9,10] ];
const oneDArr = twoDArr.reduce((accumulator, currentValue) => accumulator.concat(currentValue));
console.log(oneDArr);
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
2、展平数组删除数组中的重复性
const duplicatedsArr = [1, 5, 6, 5, 7, 1, 6, 8, 9, 7];
const removeDuplicatedArr = duplicatedsArr.reduce((accumulator, currentValue) => {
if(!accumulator.includes(currentValue)){
accumulator.push(currentValue);
}
return accumulator;
}, []);
console.log(removeDuplicatedArr);
// [ 1, 5, 6, 7, 8, 9 ]
3、按属性进行对象分组
const result = [
{subject: '物理', marks: 41},
{subject: '化学', marks: 59},
{subject: '高等数学', marks: 36},
{subject: '应用数学', marks: 90},
{subject: '英语', marks: 64},
];
let initialValue = {
pass: [],
fail: []
}
const groupedResult = result.reduce((accumulator, current) => {
(current.marks >= 50) ? accumulator.pass.push(current) : accumulator.fail.push(current);
return accumulator;
}, initialValue);
console.log(groupedResult);
输出:
{
pass: [
{ subject: ‘化学’, marks: 59 },
{ subject: ‘应用数学’, marks: 90 },
{ subject: ‘英语’, marks: 64 }
],
fail: [
{ subject: ‘物理’, marks: 41 },
{ subject: ‘高等数学’, marks: 36 }
]
}
4、 数组转对象
<!-- 按照id 取出stream -->
var streams = [{name: '技术', id: 1}, {name: '设计', id: 2}];
var obj = streams.reduce((accumulator, cur) => {accumulator[cur.id] = cur; return accumulator;}, {});
5、求对象(或者字符串)中值出现的次数
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((allNames, name) => {
const currCount = allNames[name] ?? 0;
return {
...allNames,
[name]: currCount + 1,
};
}, {});
// countedNames 的值是:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
6、数组去重
let log = console.log.bind(console);
let person = [
{id: 0, name: "小明"},
{id: 1, name: "小张"},
{id: 2, name: "小李"},
{id: 3, name: "小孙"},
{id: 1, name: "小周"},
{id: 2, name: "小陈"},
];
let obj = {};
person = person.reduce((cur,next) => {
obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
return cur;
},[]) //设置cur默认类型为数组,并且初始值为空的数组
log(person);
打印person后,我们就可以得到去重后的数组。
题外话,提到去重,很多人都会想到ES6的Set;不过根据我的实验,Set还是适合对基本类型的去重,如果Set中的每一项是对象的话,是不会去重的,j即使有的对象一模一样。
let arr = new Set([
{id: 0, name: "小明"},
{id: 0, name: "小明"},
{id: 0, name: "小明"},
{id: 0, name: "小明"}
]);
console.log([...arr]); //依旧是这4个对象
filter
筛选处数组中符合条件的项,返回一个新数组
let arr = [1,2,3,4,5];
let newArray = arr.filter((item,index)=> {
return item > 3;
});
newArray // [4,5]
arr // [1,2,3,4,5]
every
检测数组中的每一项是否符合条件,可以理解成 && '且’的关系,总结:一假即假 ,而且只要有一个元素是假,其后面的元素将不再遍历。
let arr = [1,2,3,4,5];
let res = arr.every((item,index)=> {
return item > 0;
});
console.log(arr); // [1,2,3,4,5]
console.log(res); // true
some
检测数组是否有某些项目符合条件,可以理解成 || '或’的关系,总结:一真即真
let arr = [1,2,3,4,5];
let res = arr.some((item, index) => {
return item > 4;
})
console.log(arr); // [1,2,3,4,5]
console.log(res); // true
判断对象数组中是否存在某个对象:
let result = arr.some(item => {
if (item.name == '张三') {
return true;
}
});
console.log(result); // 如果arr数组对象中含有name:'张三',就会返回true,否则返回false
if(result){ // 如果存在
// do something
}
entries(),keys() 和 values()
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象(详见《Iterator》一章),可以用for…of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"