求助:理解JavaScript基于迭代器实现的filter方法的next()逻辑
问题解答
1. next() 方法的设计逻辑
这个自定义filter函数返回的是一个同时满足可迭代、迭代器规范的对象,核心的next()方法作用就是每次被调用时,从原可迭代对象中找到第一个符合过滤规则的元素,返回标准的迭代结果对象(包含done和value属性)。
因为我们没办法提前预判要跳过多少个不符合规则的元素才能找到目标值,所以这里直接用了无限循环的语法for(;;)来持续读取原迭代器的下一个元素,直到触发返回条件。
2. 无限循环的终止逻辑
你不需要担心这个循环会无限执行,循环体内的return语句就是终止条件:只要触发以下两个条件任意一个,就会直接执行return,既终止循环,也结束本次next()方法的调用:
- 原迭代器已经遍历完全部元素,此时
v.done为true,直接返回结束标识 - 当前读取到的元素满足过滤函数
predicate的判断规则,返回当前元素的迭代结果
3. 结合你的测试用例拆解执行过程
你的测试用例中原数组是[1,2,3,4,5],过滤规则是x > 3,我们逐次看next()的执行:
- 第一次调用
iter.next():
进入循环后依次读取原迭代器的元素1、2、3,都不满足x>3的规则,所以循环持续执行;直到读取到元素4,符合过滤规则,直接返回{value: 4, done: false},循环终止。 - 第二次调用
iter.next():
原迭代器会在上一次读取的位置继续往下走,读取到元素5,符合过滤规则,返回{value: 5, done: false},循环终止。 - 第三次调用
iter.next():
原数组已经全部遍历完成,读取原迭代器返回{value: undefined, done: true},触发v.done的终止条件,直接返回该结束对象。
额外提一句:原迭代器的遍历状态是保存在filter函数的闭包中的,所以每次调用next()都会继承上一次的遍历位置,不会从头重新读取原数组。
内容的提问来源于stack exchange,提问作者Rakesh Poddar
相关产品推荐
相关产品推荐

