// 最普通最简单的for循环
const arr = [1,2,3,4,5]
for(let i = 0; i < arr.length; ++i){
console.log(arr[i]);
}
ES5新增
//forEach循环
const arr = [1,2,3,4,5]
arr.forEach(function (value){
console.log(value)
})
使用break对比
//for循环
const arr = [1,2,3,4,5]
for(let i = 0; i < arr.length; i++){
if(arr[i] === 2){
break;
//continue
}
console.log(arr[i]);
}
//forEach
arr.forEach(function (value) {
if (value === 2) { // 报错,语法不支持
break;
}
console.log(value)
})
普通for循环可以break,forEach不可以
使用continue对比
//for循环
const arr = [1,2,3,4,5]
for(let i = 0; i < arr.length; i++){
if(arr[i] === 2){
continue;
}
console.log(arr[i]);
}
//forEach
arr.forEach(function (value) {
if (value === 2) { // 报错,语法不支持
continue;
}
console.log(value)
})
普通for循环可以continue,forEach不可以
注意:
forEach不能使用break和continue,只能从头到尾遍历
every是ES5新增
const arr = [1, 2, 3, 4, 5]
//every
arr.every(function (value){
console.log(value)
})
结果是every的返回值是false,并且只输出了1就退出了,这是怎么回事?
every()
方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
every能否继续遍历取决于return的返回值,默认false,只遍历一个
注意:若收到一个空数组,此方法在一切情况下都会返回 true
。every
不会改变原数组。
那我就想让这个every和正常for循环一样遍历完数组怎么办?如下:
const arr = [1, 2, 3, 4, 5]
//every
arr.every(function (value){
console.log(value);
return true; // every能否继续遍历取决于return的返回值,默认false,只遍历一个
})
那要是想要every实现for循环的break功能怎么办呢?如下
const arr = [1, 2, 3, 4, 5]
//every
arr.every(function (value){
if (value === 3) {
return false;
}
console.log(value);
return true;
})
那要是想要every实现for循环的continue功能怎么办呢?如下
const arr = [1, 2, 3, 4, 5]
//every
arr.every(function (value){
if (value !== 3) {
console.log(value);
}
return true;
})
看了这么多绕来绕去估计都迷糊了,不知道every本来的用法是怎么样的了,看这里every
for in是ES5新增,本来就是为了遍历对象生成的,但是为什么可以遍历数组呢?因为数组是一个可遍历的对象
来看一下for in遍历数组的例子,其实是有缺陷的
const arr = [1, 2, 3, 4, 5]
for(let index in arr){
console.log(index, arr[index])
}
左边黑色的一列是索引 index,右边蓝色的一列是数组值,你先细品,等会再告诉你为什么会有两种颜色。
这么一看好像for in 遍历数组没问题啊,那我们就来看看有问题的情况。如下
const arr = [1, 2, 3, 4, 5]
arr.a = 8; // 自定义的属性,根本不是数组的属性,能添加自定义属性是因为数组也是对象
for(let index in arr){
console.log(index, arr[index])
}
明明只是想遍历数组,可以自定义属性值a却被遍历出来了,这可不是浏览器的问题!这就是缺陷,for in本来是用来遍历对象的,结果把数组包含进去了。我们再用forEach、普通for循环、every试试,直接上运行结果,结果显示,除了for in会显示自定义属性,其他的都是正常遍历数组不显示自定义属性。
那么for in会支持break和continue吗?
我们来试试
const arr = [1, 2, 3, 4, 5]
for(let index in arr){
if (index === 2) break; // 能支持break吗
console.log(index, arr[index])
}
for(let index in arr){
if (index === 2) continue; // 能支持continue吗
console.log(index, arr[index])
}
我的天,好像不支持break和continue啊?其实是支持的,还记的刚刚让你细品吗?索引是黑色的,数组值是蓝色的。黑色是告诉你这是string类型,蓝色告诉你这是number类型,而在这里我们用的 index === 2, index是"2"的时候===2肯定为假啊,所以这里是 if 里面的条件不满足导致break、continue没执行,而不是没生效!
我们来看看正常情况
const arr = [1, 2, 3, 4, 5]
for(let index in arr){
if (index == 2) break; // 支持break
console.log(index, arr[index])
}
for(let index in arr){
if (index == 2) continue; // 支持continue
console.log(index, arr[index])
}
关于类型,你可以typeof index打印就知道是string类型了
那怎么样才能满足 === 呢
if(index * 1 === 2)即可
字符串数值*1相当于Number(),也就是说"2" * 1等同于Number(2)
const arr = [1, 2, 3, 4, 5]
for(let index in arr){
if (index * 1 === 2) break; // 支持break
console.log(index, arr[index])
}
for of是ES6新增,数组Array的遍历用普通for循环和forEach就好,Object的遍历用for in就好,用for of直接遍历就报错了。
// for of普通用法
let arr = [1,2,3,4,5]
for(let item of arr){
console.log(item)
}
for of直接遍历对象报错演示
const obj = {
name: "lcy",
age: 18
};
for (let value of obj) {
console.log(value);
}
那对象用for of就无法遍历了吗?办法是有的
const obj = {
name: "lcy",
age: 18
};
for (let value of Object.values(obj)) {
console.log(value);
}
这样value值就遍历出来了,那么我想遍历key值可以吗?当然可以
const obj = {
name: "lcy",
age: 18
};
for (let value of Object.keys(obj)) {
console.log(value);
}
同时获取属性名和值的键值对也是可以的,如下操作
const obj = {
name: "lcy",
age: 18
};
for (let array of Object.entries(obj)) {
console.log(array);
}
也可以使用扩展语法同时获取属性名与值
const obj = {
name: "lcy",
age: 18
};
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
ES6之后允许自定义数据结构,可以不是数组,不是Object,用普通for循环、forEach、every、for in都没办法直接遍历,而要用到for of。