视频加载失败

ES6遍历器与for…of循环

1469 字
7 分钟
ES6遍历器与for…of循环

Iterator 是什么#

  • Iterator(迭代器) 是 JavaScript 中一个统一遍历数据结构的机制,核心作用一句话:让不同的数据结构都能用同一种方式逐个访问元素

Iterator的作用

//遍历器 遍历;Iterator就是用来遍历
for (let i = 1; i < 5; i++) {
console.log(i);
}
[1, 2, 3].forEach((value) => {
console.log(value);
});
new Set([11, 12, 13]).forEach((value) => {
console.log(value);
});

寻找Iterator

//2025年才新增的全局构造函数,有些旧版浏览器不支持,打印出来就报错
console.log(Iterator);//ƒ Iterator() { [native code] }
//通过数组的Prototype可以看到 Symbol(Symbol.iterator)
console.log([1, 2]);
//调用执行
console.log([1, 2][Symbol.iterator]());

使用Iterator

const it = [1, 2][Symbol.iterator]();
console.log(it.next()); //{value: 1, done: false}
console.log(it.next()); //{value: 2, done: false}
console.log(it.next()); //{value: undefined, done: true}
//it 可遍历对象
//Symbol.iterator 可遍历对象的生成方法

Iterator 解惑#

为什么需要Iterator 遍历器

//数组可以用for或者佛forEach方法
//对象可以用for in
//Iterator 并不是为数组和对象遍历,而是统一遍历方式
console.log([][Symbol.iterator]()); //Array Iterator {} 天生具备
console.log({}[Symbol.iterator]); //undefined 不具备

如何更方便的使用Iterator

// Symbol.iterator->it->next()
//我们一般不会直接使用Iteratr去遍历->封装成一个函数
// for..of

for…of 的用法#

  • for...of 是 ES6 新增的循环语法,用来遍历可迭代对象(Iterable)中的值。

  • for...of 用来遍历可迭代对象的value值,它的底层就是不断调用 Iterator 的 next() 方法。

    //基本语法
    for (const item of iterable) {
    // 使用 item
    //item每次遍历得到的值
    //iterable可迭代对象
    }
    //遍历数组,没有索引
    const arr = [10, 20, 30];
    for (const item of arr) {
    console.log(item);
    }
    //遍历字符串
    const str = 'hello';
    for (const ch of str) {
    console.log(ch);
    }
    //遍历 Set
    const set = new Set([1, 2, 3]);
    for (const item of set) {
    console.log(item);
    }
    //遍历 Map
    const map = new Map([
    ['name', 'Alice'],
    ['age', 18]
    ]);
    for (const item of map) {
    console.log(item);
    }
    for (const [key, value] of map) {
    console.log(key, value);
    }
    //遍历 DOM 集合
    const ps = document.querySelectorAll('p');
    for (const p of ps) {
    console.log(p);
    }
    //不能直接遍历 Object
    const obj = {
    name: 'Alice',
    age: 18
    };
    for (const item of obj) {}//报错
    //遍历键
    for (const key of Object.keys(obj)) {
    console.log(key);
    }
    //遍历值
    for (const value of Object.values(obj)) {
    console.log(value);
    }
    //遍历键和值
    for (const [key, value] of Object.entries(obj)) {
    console.log(key, value);
    }
    //可以配合 break、continue forEach没有break、continue,这是区别
    for (const n of [1, 2, 3, 4, 5]) {
    if (n === 3) break;
    console.log(n);
    }
    for (const n of [1, 2, 3, 4]) {
    if (n % 2 === 0) continue;
    console.log(n);
    }
    //数组遍历时拿索引怎么办for...of 默认只有值,没有索引。
    const arr = [1, 2, 3];
    console.log(arr.keys());
    for (const key of arr.keys()) {
    console.log(key);
    }
    for (const value of arr) {
    console.log(value);
    }
    //方法 1:entries() 既想得带value和key
    const arr = ['a', 'b', 'c'];
    for (const [index, value] of arr.entries()) {
    console.log(index, value);
    }

for…of、for…in、forEach、for、while区别#

一、核心区别表

特性forwhilefor...offor...inforEach
类型循环语句循环语句循环语句循环语句数组方法
遍历内容自己控制自己控制值(value)键(key)值(value)
是否需要索引自己维护自己维护默认没有键本身自带 index
支持数组✅✅✅⚠️ 不推荐✅
支持对象 Object✅✅❌✅❌
支持 Set✅✅✅❌✅
支持 Map✅✅✅❌✅
支持 String✅✅✅⚠️ 可用但少见❌
支持 NodeList✅✅✅⚠️ 可用但少见部分环境支持
支持 Generator✅✅✅❌❌
支持 break✅✅✅✅❌
支持 continue✅✅✅✅❌
支持 return 退出函数✅✅✅✅❌(只能退出回调)
支持 await✅✅✅✅❌
会遍历原型链属性自己控制自己控制❌✅
底层依赖 Iterator❌❌✅❌❌

二、最常见使用场景

场景推荐
普通数组遍历for...of
需要索引for
需要中途退出for、for...of
需要 awaitfor...of
遍历 Objectfor...in、Object.entries()
遍历 Mapfor...of
遍历 Setfor...of
无限循环while
简单数组遍历forEach

三、获取的东西不一样(最容易混)

假设:

const arr = ['a', 'b', 'c'];
const obj = {
name: 'Alice',
age: 18
};

for

for (let i = 0; i < arr.length; i++) {
console.log(i, arr[i]);
}
//0 a
//1 b
//2 c

for...of

for (const v of arr) {
console.log(v);
}
//a
//b
//c

for...in

for (const k in arr) {
console.log(k);
}
//0
//1
//2

forEach

arr.forEach((v, i) => {
console.log(i, v);
});
//0 a
//1 b
//2 c

while

let i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
//输出;abc

四、为什么数组不推荐 for...in?

Array.prototype.test = 'hello';
const arr = [1, 2, 3];
for (const k in arr) {
console.log(k);
}
//输出:
//0
//1
//2
//test

因为:for...in 遍历的是可枚举属性,包括原型链上的属性。所以:❌不推荐遍历数组。

五、实际开发怎么选?

数组

for (const item of arr) {}

数组 + 索引

for (let i = 0; i < arr.length; i++) {}
//或者:
for (const [i, item] of arr.entries()) {}

对象

for (const [k, v] of Object.entries(obj)) {}

Map

for (const [k, v] of map) {}

Set

for (const v of set) {}

异步循环

for (const item of arr) {
await fn(item);
}

记忆口诀

for —— 最灵活
while —— 条件循环
for...of —— 遍历值(Iterator)
for...in —— 遍历键(Object)
forEach —— 数组工具方法

一句话总结

数组优先 for...of,对象优先 Object.entries(),需要索引用 for,需要异步用 for...of,简单遍历可以用 forEach。

原生可遍历和非原生可遍历#

哪些对象天生(原生)支持 for...of,哪些对象默认不支持。

判断标准只有一个:

typeof obj[Symbol.iterator] === 'function'
//有这个方法:原生可遍历(Iterable);没有:非原生可遍历(Non-Iterable)

原生可遍历对象

类型for...ofSymbol.iterator
Array✅有
String✅有
Set✅有
Map✅有
NodeList✅有
TypedArray✅有
Generator 返回对象✅有
arguments(现代浏览器)✅有
//Array
const arr = [1, 2, 3];
for (const x of arr) {
console.log(x);
}
//String
for (const ch of 'abc') {
console.log(ch);
}
//Set
const set = new Set([1, 2, 3]);
for (const x of set) {
console.log(x);
}
//Map
const map = new Map([
['name', 'Alice'],
['age', 18]
]);
for (const [k, v] of map) {
console.log(k, v);
}
//NodeList
const ps = document.querySelectorAll('p');
for (const p of ps) {
console.log(p);
}

非原生可遍历:

数据类型原生可遍历
Object❌
Function❌
Date❌
RegExp❌

使用了 Iterator 的场合#

场合总结:

场景是否使用 Iterator
for...of✅
... 扩展运算符✅
解构赋值✅
yield*✅
Array.from()✅
new Set(iterable)✅
new Map(iterable)✅
Promise.all()✅
Promise.race()✅
Promise.any()✅
Promise.allSettled()✅
Iterator.from()✅

特例:

//数组解构赋值,原生可遍历的都可以被解构赋值
const[a,b] = 'hi'
//等价于,因为字符串可以天生遍历
const[a,b] = [...'hi']
//因为Set可以天生遍历
const[a,b] = new Set([3,2])

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ES6遍历器与for…of循环
https://f.youzi177.cn/posts/2026102109es6-bian-li-qi-yu-forof-xun-huan/
作者
小封鸭
发布于
2026-10-21
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录