for in、for of 、forEach 区别
for of 常用于异步遍历,for in、forEach、 for 多用于 同步遍历。
一、 基本用法
1. 遍历数组:
for of 遍历数组
1 | let nums = [1,2,3] |
for in 遍历数组
1 | for(i in nums) { |
forEach 遍历数组
1 | nums.forEach((value,key)=>{ |
2. 遍历对象:
1 | let obj = { |
for in 遍历对象,不能遍历map、set,不报错,但由于没有key会返回undefined
1 | for(i in obj) { |
for of、forEach 不能遍历对象
1 | for(i of obj) { |
for of 只能遍历有iterable(遍历器)接口的变量,object没有遍历器接口。
原生具备 Iterator 接口的数据结构如下。Array、Map、Set、String、TypedArray 函数的 arguments 对象、NodeList 对象
forEach也不能遍历对象,但可以用Object.keys() Object.values() Object.entries(obj)去遍历对象
插一句:set和map也有对应的values keys entries方法,返回的是各自类型的键组合、值组合、键值对类型组合,可以用for of 沙发垫
二、 forEach 和 for of 区别
1. 遍历对象方面
for of 可以遍历的:
实现了迭代器接口,即具有[Symbol.iterator]方法,它们可以被for...of用于遍历。
forEach可以遍历的:
数组和类数组对象,即:拥有length属性(这是我自己认为的,不一定对,反正暂时没出错)。
forEach不能遍历而for of可以遍历的
forEach可以做的for of基本都可以做,但有些有iterator接口的变量,只能用for of来做。
如生成器函数(generator)、字符串的Symbol迭代器、自定义的迭代器对象等
(1). 生成器函数(Generator Functions):
1 | function* generateSequence() { |
(2). 字符h 串的Symbol迭代器:
1 | const str = "Hello"; |
(3). 自定义迭代器对象
1 | const customIterator = { |
2. for of 的异步遍历
如果使用foreach遍历处理异步代码不会等待异步代码的执行,一次输出所有异步结果
使用forEach打印一次性打印出了1、4、9
1 | function muti(num) { |
如果使用for of可以使异步按先后顺序执行
使用for of打印就可以实现每隔一秒进行打印1、4、9
1 |
|
3. for of 异步遍历的例子
关于异步处理方面的区别,在使用for...of遍历可迭代对象时,可以使用await关键字来等待异步操作的完成。
而forEach方法本身是同步的,无法直接使用await等待异步操作。
以下是一个使用for...of进行异步处理的例子,其中包含了await关键字:
1 | async function processArray(arr) { |
在上述例子中,processArray函数使用for...of遍历数组,并通过await等待异步操作的完成。每个元素的处理会等待一秒钟,然后才会处理下一个元素。
相比之下,forEach方法无法直接实现类似的异步处理,因为它本身是同步的,无法等待异步操作的完成。