Iterator迭代器 【ES6】

学无止境

目录

Iterator是什么?

在前端开发中,迭代器(Iterator) 是一种用于遍历数据集合的接口。迭代器提供了一种统一的方式来访问集合中的元素,而无需暴露集合的内部结构。

Iterator作用:

引言:需要遍历的每个值 数组可以通过for循环-索引值找到;对象可以通过for-in找到;那么Set呢?Map呢?要通过什么方式能找到? 由于数据结构太多,所以:

  • 为各种数据结构提供一个统一的、简便的访问接口
  • 是的数据结构的成员能够按某种次序排列
  • for...of循环(ES6新创的遍历命令;Iterator主要用for...of循环)

遍历过程:

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员
  3. 第二次调用指针对象的next方法,指针指向数据结构的第二个成员
  4. 不断调用只针对想的next方法,直到它指向数据结构的结束位置
javascript 复制代码
const array = [1, 2, 3, 4, 5];
// 获取数组的迭代器
const iterator = array[Symbol.iterator]();
// 使用迭代器遍历数组
let result = iterator.next();
while (!result.done) {
   console.log(result.value);
   result = iterator.next();
}

结果如下:

深入剖析:

哪些数据结构自带 Symbol.iterator?

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性(一个数据结构只要有Symbol.iterator属性,就可以认为是可遍历的)

数据类型 是否可迭代 示例
Array ✅ 有 [1,2,3][Symbol.iterator]()
String ✅ 有 "abc"[Symbol.iterator]()
Map ✅ 有 new Map()[Symbol.iterator]()
Set ✅ 有 new Set()[Symbol.iterator]()
TypedArray(如 Int8Array) ✅ 有 new Int8Array()[Symbol.iterator]()
Arguments(类数组对象 Array-like Object) ✅ 有 function fn(){ arguments[Symbol.iterator]() }
DOM NodeList(节点集合,类数组) ✅ 有 document.querySelectorAll('div')[Symbol.iterator]()
Object(普通对象) ❌ 默认没有 {a:1}[Symbol.iterator] // undefined

为什么普通对象不能 for...of?

因为它 没有实现 Symbol.iterator。【对象是非线性的

javascript 复制代码
const obj = { a: 1, b: 2 };

for (const x of obj) {   // ❌ TypeError: obj is not iterable
  console.log(x);
}

console.log(obj[Symbol.iterator]); // undefined

让对象变成可迭代的:

加一个 Symbol.iterator 方法:

javascript 复制代码
const obj = {
  a: 1,
  b: 2,
  [Symbol.iterator]() {
    const entries = Object.entries(this)
    let index = 0
    return {
      next() {
        if (index < entries.length) {
          return { value: entries[index++], done: false }
        } else {
          return { done: true }
        }
      }
    }
  }
}

for (const [k, v] of obj) {
  console.log(k, v); // a 1 / b 2
}
javascript 复制代码
let obj = {
   code:200,
   name:'obj',
   list:['a','b','c'],
   [Symbol.iterator](){
     let index = 0;
     return {
       next:()=>{
         if(index<this.list.length){
           return {done:false,value:this.list[index++]}
         }else{
           return {done:true,value:null}
         }
       }
     }
   }
}

for(let item of obj){
    console.log(item); // a <br/> b <br/> c
}

结论:

只要一个对象拥有 obj[Symbol.iterator]() 方法,它就是一个"可迭代对象",可以被 for...of、... 等语法使用。

简单构造迭代器的方法:

javascript 复制代码
function getIterator(list) {
    let i = 0;
    return {
        next: function () {
            let done = (i >= list.length);
            let value = done ? undefined : list[i++];
            return {
                value: value,
                done: done
            };
        }
    };
}
const arr = getIterator(['a', 'b', 'c']);
console.log(arr.next());// {value: "a", done: false}
console.log(arr.next());// {value: "b", done: false}
console.log(arr.next());// {value: "c", done: false}
console.log(arr.next());// "{ value: undefined, done: true }"
相关推荐
葱头的故事3 小时前
将传给后端的数据转换为以formData的类型传递
开发语言·前端·javascript
中微子3 小时前
🚀 2025前端面试必考:手把手教你搞定自定义右键菜单,告别复制失败的尴尬
javascript·面试
一念&4 小时前
每日一个C语言知识:C 数组
c语言·开发语言·算法
小年糕是糕手4 小时前
【数据结构】单链表“0”基础知识讲解 + 实战演练
c语言·开发语言·数据结构·c++·学习·算法·链表
疯狂吧小飞牛4 小时前
Lua C API 中的 lua_rawseti 与 lua_rawgeti 介绍
c语言·开发语言·lua
Tony Bai4 小时前
【Go 网络编程全解】06 UDP 数据报编程:速度、不可靠与应用层弥补
开发语言·网络·后端·golang·udp
半夏知半秋4 小时前
lua对象池管理工具剖析
服务器·开发语言·后端·学习·lua
whyfail4 小时前
React v19.2版本
前端·javascript·react.js
大飞记Python4 小时前
Windows10停服!7-Zip被爆组合漏洞|附安全指南
开发语言