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..offor…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);}//遍历 Setconst set = new Set([1, 2, 3]);for (const item of set) {console.log(item);}//遍历 Mapconst 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);}//不能直接遍历 Objectconst 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和keyconst arr = ['a', 'b', 'c'];for (const [index, value] of arr.entries()) {console.log(index, value);}
for…of、for…in、forEach、for、while区别
一、核心区别表
| 特性 | for | while | for...of | for...in | forEach |
|---|---|---|---|---|---|
| 类型 | 循环语句 | 循环语句 | 循环语句 | 循环语句 | 数组方法 |
| 遍历内容 | 自己控制 | 自己控制 | 值(value) | 键(key) | 值(value) |
| 是否需要索引 | 自己维护 | 自己维护 | 默认没有 | 键本身 | 自带 index |
| 支持数组 | ✅ | ✅ | ✅ | ⚠️ 不推荐 | ✅ |
| 支持对象 Object | ✅ | ✅ | ❌ | ✅ | ❌ |
| 支持 Set | ✅ | ✅ | ✅ | ❌ | ✅ |
| 支持 Map | ✅ | ✅ | ✅ | ❌ | ✅ |
| 支持 String | ✅ | ✅ | ✅ | ⚠️ 可用但少见 | ❌ |
| 支持 NodeList | ✅ | ✅ | ✅ | ⚠️ 可用但少见 | 部分环境支持 |
| 支持 Generator | ✅ | ✅ | ✅ | ❌ | ❌ |
| 支持 break | ✅ | ✅ | ✅ | ✅ | ❌ |
| 支持 continue | ✅ | ✅ | ✅ | ✅ | ❌ |
| 支持 return 退出函数 | ✅ | ✅ | ✅ | ✅ | ❌(只能退出回调) |
| 支持 await | ✅ | ✅ | ✅ | ✅ | ❌ |
| 会遍历原型链属性 | 自己控制 | 自己控制 | ❌ | ✅ | |
| 底层依赖 Iterator | ❌ | ❌ | ✅ | ❌ | ❌ |
二、最常见使用场景
| 场景 | 推荐 |
|---|---|
| 普通数组遍历 | for...of |
| 需要索引 | for |
| 需要中途退出 | for、for...of |
需要 await | for...of |
| 遍历 Object | for...in、Object.entries() |
| 遍历 Map | for...of |
| 遍历 Set | for...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 cfor...of
for (const v of arr) { console.log(v);}//a//b//cfor...in
for (const k in arr) { console.log(k);}//0//1//2forEach
arr.forEach((v, i) => { console.log(i, v);});//0 a//1 b//2 cwhile
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...of | Symbol.iterator |
|---|---|---|
Array | ✅ | 有 |
String | ✅ | 有 |
Set | ✅ | 有 |
Map | ✅ | 有 |
NodeList | ✅ | 有 |
TypedArray | ✅ | 有 |
| Generator 返回对象 | ✅ | 有 |
arguments(现代浏览器) | ✅ | 有 |
//Arrayconst arr = [1, 2, 3];for (const x of arr) { console.log(x);}
//Stringfor (const ch of 'abc') { console.log(ch);}
//Setconst set = new Set([1, 2, 3]);
for (const x of set) { console.log(x);}
//Mapconst map = new Map([ ['name', 'Alice'], ['age', 18]]);for (const [k, v] of map) { console.log(k, v);}
//NodeListconst 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])文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
ES6对象字面量的增强与函数参数默认值
前端工程师2026-10-21
2
ES6类Class
前端工程师本文主要学习ES6类Class
3
ES6异步Promise
前端工程师本文主要学习ES6异步Promise
4
ES6新增方法
前端工程师本文主要学习ES6新增方法
5
ES6剩余参数
前端工程师2026-10-21
随机文章随机推荐














