带你领略JavaScript数组遍历你压根没想过的惊艳操作

 

目录

入门级通用for循环

forEach

forEach和普通for循环居然还有区别?

用every也能实现数组遍历?

for in遍历数组为什么会有问题?

for of (可别犯常规错误)


 

入门级通用for循环

// 最普通最简单的for循环
const arr = [1,2,3,4,5]
for(let i = 0; i < arr.length; ++i){
	console.log(arr[i]);
}

 

forEach

ES5新增

//forEach循环
const arr = [1,2,3,4,5]
arr.forEach(function (value){
    console.log(value)
})

forEach和普通for循环居然还有区别?

使用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也能实现数组遍历?

every是ES5新增

const arr = [1, 2, 3, 4, 5]
//every
arr.every(function (value){
    console.log(value)
})

结果是every的返回值是false,并且只输出了1就退出了,这是怎么回事?

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

every能否继续遍历取决于return的返回值,默认false,只遍历一个

注意:若收到一个空数组,此方法在一切情况下都会返回 trueevery 不会改变原数组。

那我就想让这个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遍历数组为什么会有问题?

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 (可别犯常规错误)

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。

 

关注、留言,我们一起学习。

 

===============Talk is cheap, show me the code================

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页