迭代协议
迭代协议
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols
作为ECMAScript2015的一组补充规范,迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。
迭代协议具体分为两个协议:可迭代协议和迭代器协议
可迭代协议
可迭代协议允许JavaScript对象定义或定制它们的迭代行为,例如,在一个for...of结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如Array或者Map,而其他内置类型则不是(比如Object)。
要成为可迭代对象,一个对象必须实现@@iterator方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为@@iterator的属性,可通过常量Symbol.iterator访问该属性
属性 | 值 |
[Symbol.iterator] | 返回一个符合迭代器协议的对象的无参数函数。 |
当一个对象需要被迭代的时候(比如被置入一个for...of循环时),首先,会不带参数调用它的@@iterator方法,然后使用此方法返回的迭代器要获得迭代的值。
值得注意的是调用此零个参数函数时,它将作为可迭代对象的方法进行调用。因此,在函数内部,this关键字可用于访问可迭代对象的属性,以决定在迭代过程中提供什么。
迭代器协议
迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认值。
只有实现了一个拥有以下语义的next()方法,一个对象才能成为迭代器:
属性 | 值 |
next |
一个无参数函数,返回一个应当拥有以下两个属性的对象: done(boolean) 如果迭代器可以产生序列中的下一个值,则为false。(这等价于没有指定done这个属性) 如果迭代器已将序列迭代完毕,则为true.这种情况下,value是可选的,
value 迭代器返回的任何JavaScript值,done为true时可省略
next()方法必须返回一个对象,该对象应当有两个属性:done和value,如果返回了一个非对象值(比如false或undefined),则会抛出一个TypeError异常("iterator.next() returned a non-object value") |
备注:不可能判断一个特定的对象是否实现了迭代器协议,然而,创造一个同时满足迭代器协议和可迭代协议的对象是很容易的
var myIterator = { next: function () { // ... }, [Symbol.iterator]: function() { return this; }; }
使用迭代协议的例子
String是一个内置的可迭代对象
let someString = "Hi"; typeof someString[Symbol.iterator]; // "function"
String的默认迭代器会依次返回该字符串的各码点
let iterator = someString[Symbol.iterator](); iterator + ""; // "[object String Iterator]" iterator.next(); // { value: "h", done: false} iterator.next(); // { value: "i", done: false} iterator.next(); // { value: undefined, done: true}
一些内置的语法结构——比如展开语法——其内部实现也使用了同样的迭代协议:
[...someString] // ["h", "i"]
我们可以通过提供自己的@@iterator方法,重新定义迭代行为:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
2020-08-30 Angular中的可观察对象