JavaScript用箭头函数实现Group类可迭代时报错如何解决
报错根因解析
第一个ReferenceError: next is not defined的触发逻辑
你在class的方法里写了return next = () => {},本质是直接给未通过let/const/var声明的next标识符做赋值。JS类内部的所有代码默认运行在严格模式下,严格模式禁止未声明变量的隐式全局挂载,这种直接赋值的操作会直接抛出引用错误,和迭代逻辑本身半毛钱关系都没有。
第二个TypeError: undefined is not a function的触发逻辑
这里是你对可迭代协议/迭代器协议的规则理解有偏差,属于新手接触可迭代能力时非常常见的踩坑点:
- 规范要求,对象上的
[Symbol.iterator]方法,调用后必须返回一个符合迭代器协议的对象 - 这个迭代器对象必须挂载一个名为
next的方法,每次调用next才会返回包含done(标识迭代是否结束)和value(当前迭代值)的结果对象
你之前直接把匿名箭头函数作为[Symbol.iterator]的返回值,引擎拿到这个返回对象后,会尝试调用它身上的next方法,自然只能拿到undefined,从而抛出类型错误。
另外你想用箭头函数固定this指向的思路本身是对的:箭头函数没有自己的this,会沿用定义时的外层this(也就是当前Group类的实例),完全可以避免传统普通写法里存const self = this的冗余,只是返回值的结构不符合规范要求。
最小改动的正确实现
直接在你原有代码的基础上修正两处问题即可:
- 对
next函数做显式声明,消除严格模式下的赋值报错 - 把
next方法挂载到对象上作为返回值,对齐迭代器协议要求
修正后的[Symbol.iterator]代码如下:
[Symbol.iterator]() { let i = 0; // 箭头函数自动绑定当前实例的this,和你原来写的迭代逻辑完全一致 const next = () => { if (i >= this.theGroup.length) { return { done: true }; } return { value: this.theGroup[i++], done: false }; }; // 必须返回带next方法的迭代器对象,不能直接返回next函数本身 return { next }; }
更简洁的优化写法
因为你存储值的底层容器theGroup本身是原生JS数组,已经完全实现了标准的迭代器接口,完全可以复用原生的迭代逻辑,省去自己维护索引计数的代码:
[Symbol.iterator]() { // 直接透传数组的原生迭代器,完全符合规范 return this.theGroup[Symbol.iterator](); }
这种写法性能更好,也不容易出现索引维护的边界错误。
内容的提问来源于stack exchange,提问作者anotherOne
相关产品推荐
相关产品推荐

