普通对象不可迭代,是因为未实现Symbol.iterator方法;for...of依赖该方法获取迭代器,而普通对象既非原生可迭代类型,也未手动部署该方法,故报错“is not iterable”。

因为普通对象(比如 {a: 1, b: 2})默认没有实现迭代器协议,for...of 无法从中获取迭代逻辑,所以会抛出 TypeError: obj is not iterable。
核心原因:缺少 Symbol.iterator 方法
for...of 的底层机制是调用对象的 [Symbol.iterator]() 方法,拿到一个迭代器对象(含 next()),再反复调用它来取值。而普通对象的原型链上没有这个方法,既不是原生可迭代类型(如 Array、Map、Set、String),也没有手动部署它。
- 数组、Map、字符串等内置类型都预置了
Symbol.iterator - 普通对象字面量
{}或Object.create(null)都不带该属性 - 即使对象有自有属性,
for...of也不会自动“猜”你要遍历键、值还是键值对
和 for-in 的本质区别
for...in 是专为对象设计的语句,它遍历的是对象**可枚举的自有及继承属性名**(即 key),不依赖任何接口;而 for...of 是通用迭代协议的使用者,只关心对象是否“声明自己支持迭代”,跟数据结构类型无关。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
for...in obj→ 检查属性枚举性 → 可以运行 -
for...of obj→ 查找obj[Symbol.iterator]→ 返回undefined→ 报错
为什么设计成这样?
ES6 的迭代协议强调**明确性与一致性**:不同结构应主动表明“我支持哪种遍历方式”。对象本身是无序、无固有遍历顺序的键值容器,JS 不强制规定“遍历对象就等于遍历 keys”——这由开发者通过 Object.keys()、Object.values() 或自定义迭代器来决定。
立即学习“Java免费学习笔记(深入)”;
- 避免歧义:遍历对象时,你想要的是 key?value?还是
[key, value]? - 保持接口正交:让
for...of专注“如何迭代”,把“迭代什么”交给数据源自己定义
快速验证方法
在控制台输入以下代码,就能确认对象是否可迭代:
const obj = { x: 1, y: 2 };
console.log(obj[Symbol.iterator]); // undefined → 不可迭代
console.log([1, 2][Symbol.iterator]); // function values() → 可迭代

















