判断一个值是否为可迭代类型,最直接可靠的方式是检测其是否存在 symbol.iterator 属性且该属性为函数。es6 规范规定,只要对象拥有可调用的 symbol.iterator 方法即为可迭代,支持 for...of 等操作;不能依赖构造函数名、原型链或 length 属性,需同时满足属性存在和类型为函数两个条件。

判断一个值是否为可迭代类型,最直接可靠的方式是检测其是否存在 Symbol.iterator 属性,并且该属性是一个函数。
为什么检测 Symbol.iterator 是关键
ES6 规范定义:只要一个对象拥有可被调用的 Symbol.iterator 方法,它就是可迭代的(iterable)。这个方法返回一个迭代器对象,支持 for...of、展开运算符([...obj])、Array.from() 等操作。
注意:不能只靠构造函数名(如 Array、Map)或原型链判断,因为用户可自定义可迭代对象;也不能仅检查是否为类数组(如 length 属性),因为字符串、Set、自定义对象等也符合但无 length 或类型不匹配。
安全的检测写法
需同时满足两个条件:属性存在 + 类型为函数。推荐写法如下:
- 使用
typeof obj[Symbol.iterator] === 'function' - 避免直接调用(防止副作用或报错),不写
obj[Symbol.iterator]() - 兼容性考虑:若环境不支持
Symbol(如旧版 IE),可先检测Symbol是否存在,但现代项目通常无需降级处理
常见误判场景与规避
以下情况容易出错,需特别注意:
-
空对象或 null/undefined:它们没有
Symbol.iterator,检测结果为false,正确 -
NodeList、HTMLCollection:现代浏览器中它们实现了
Symbol.iterator,是可迭代的;但旧版需 polyfill 或用Array.from兜底 -
Generator 函数本身不可迭代,其调用结果才可迭代:即
genFunc不可迭代,genFunc()才是 -
只读属性或 getter 报错:极少数对象可能将
Symbol.iterator定义为 getter 且抛错,建议用try/catch包裹(生产环境慎用,多数标准对象不会如此)
实用工具函数示例
可封装成简洁的判断函数:
function isIterable(obj) {
return obj != null
&& typeof obj[Symbol.iterator] === 'function';
}
使用示例:
-
isIterable([1,2,3])→true -
isIterable('abc')→true -
isIterable(new Set())→true -
isIterable({})→false -
isIterable(null)→false











