string 和 array 的 iterator 接口由引擎底层实现,每次调用 [symbol.iterator] 都返回全新、独立、状态隔离的迭代器;array 按索引顺序遍历元素,string 按 utf-16 编码单元惰性访问;object 无默认迭代器因其属性无可靠固有顺序。

String 和 Array 等原生内置类的 Iterator 接口不是“手动写死”的逻辑,而是由 JavaScript 引擎在底层用符合规范的方式实现的——它们在原型上部署了 [Symbol.iterator] 方法,该方法每次调用都返回一个**全新、独立、状态隔离**的迭代器对象。
Array 的默认实现特点
Array.prototype[Symbol.iterator] 实际指向 Array.prototype.values()(也等价于 Array.prototype[Symbol.iterator] 本身)。它返回一个内部构造的 Array Iterator 对象,具备以下关键行为:
- 每次调用都创建新实例,所以多个
for...of循环或展开运算符互不影响 - 内部维护一个索引计数器(从 0 开始),
next()每次返回当前索引对应的元素,并递增计数器 - 当索引超出数组长度时,
done设为true,后续所有next()都稳定返回{ value: undefined, done: true } - 不依赖外部闭包或共享变量,避免状态污染
String 的默认实现特点
String.prototype[Symbol.iterator] 返回一个基于 UTF-16 编码单元的字符迭代器(注意:不是按 Unicode 字符,而是按 code unit;对 emoji 或代理对需额外处理):
- 把字符串视为只读的字符序列,按索引逐个提取
str[i] - 同样每次调用生成新迭代器,支持多次遍历
- 对空字符串,第一次
next()就返回{ value: undefined, done: true } - 不修改原始字符串,也不缓存中间结果,属于轻量级惰性访问
统一机制:引擎级标准化实现
这些内置类型的 [Symbol.iterator] 并非用 JavaScript 代码公开实现,而是由 V8(Chrome/Node)、SpiderMonkey(Firefox)、JavaScriptCore(Safari)等引擎用 C++ 或优化汇编实现,但严格遵循 ECMAScript 规范:
- 必须是无参函数,且返回对象满足 Iterator 协议(有
next()方法,返回{ value, done }) - 返回的迭代器对象自身也实现了
[Symbol.iterator]() { return this; },因此它自己也是可迭代的 - 不暴露内部状态,用户无法直接修改计数器或重置位置
- 与
for...of、[...str]、Array.from(str)、Promise.all(arr)等语言特性深度绑定
为什么 Object 没有默认 Iterator?
因为普通对象的属性没有固有顺序(ES2015+ 虽规定了部分插入顺序,但仍不构成可靠遍历依据),引擎无法定义一个“合理默认”的线性遍历路径。若强行实现,可能引发歧义或性能问题。开发者如需遍历对象,需显式用 Object.keys()、Object.entries() 或自定义 [Symbol.iterator]。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











