遍历器 Iterator

Iterator是JavaScript中的一种统一的遍历接口,用于不同数据结构的遍历操作。它提供了一个指针对象,通过next方法按顺序访问数据结构的所有成员。for...of循环依赖于Iterator接口。默认的Iterator接口在数据结构的Symbol.iterator属性上,如Array、Map、Set等原生支持。此外,可以通过Generator函数或手动实现Iterator接口,例如将类数组转换为数组。在遍历过程中,return和throw方法可用于处理提前退出或资源清理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。

Iterator 的遍历过程是这样的。

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,并且如果Symbol.iterator方法对应的不是遍历器生成函数,会报错

原生具备 Iterator 接口的数据结构如下。
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象

我们可以把数组的Symbol.iterator属性赋给类数组,再用扩展运算符,实现类数组转数组

之前写过自己实现Iterator接口

Object.defineProperty(myObject, Symbol.iterator, {
    enumerable: false,
    writable:false,
    configurable:false,
    value:function(){
        let o = this;
        let idx = 0;
        let ks = Object.keys(o);
        return {
            next:function(){
                return {
                    value:o[ks[idx++]],
                    done:(idx>ks.length)
                }
            }
        }
    }
});

其实还有一种更简单粗暴的实现方式,用Generator 函数

let myIterable = {
  [Symbol.iterator]: function* () {
    yield 1; //根据情况写表达式
    yield 2;
    yield 3;
  }
}
[...myIterable] // [1, 2, 3]

遍历器next方法最重要,但除了它还有return和throw方法,return方法的使用场合是,如果for…of循环提前退出(通常是因为出错,或者有break语句或continue语句),就会调用return方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return方法。

function readLinesSync(file) {
  return {
    [Symbol.iterator]() {
      return {
        next() {
          return { done: false };
        },
        return() {
          file.close();
          return { done: true };
        }
      };
    },
  };
}
//触发return
// 情况一  输出文件的第一行以后,就会执行return方法,关闭这个文件
for (let line of readLinesSync(fileName)) {
  console.log(line);
  break;
}

// 情况二  输出所有行以后,执行return方法,关闭该文件
for (let line of readLinesSync(fileName)) {
  console.log(line);
  continue;
}

// 情况三  会在执行return方法关闭文件之后,再抛出错误
for (let line of readLinesSync(fileName)) {
  console.log(line);
  throw new Error();
}

ES6 的数组、Set、Map 都部署了以下三个方法,调用后都返回遍历器对象(Object.keys等与他们不同,返回的是数组)
entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。
keys() 返回一个遍历器对象,用来遍历所有的键名。
values() 返回一个遍历器对象,用来遍历所有的键值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值