JavaScript中while循环直接调用iterator.next()仅输出1的原因
造成输出差异的核心原因
迭代器的next()方法不是纯函数,每次调用都会推进迭代器内部的遍历指针,消耗一个迭代位置,不存在“调用多次返回同一个结果”的特性。第二段代码在循环判断和循环体里各调用了一次next(),每轮循环会消耗两个迭代位置,直接跳过了大部分元素,还提前触发了迭代终止条件。
第一段正常输出的代码执行逻辑
const str = '123'; const iterator = str[Symbol.iterator]() let charAt = iterator.next() while (!charAt.done) { console.log(charAt.value) charAt = iterator.next() }
这段代码每轮循环只会调用一次next(),迭代器指针逐位推进:
- 初始首次调用
next(),拿到第一个字符'1',判断done为false进入循环 - 打印
'1',第二次调用next()拿到第二个字符'2' - 判断
'2'的done为false进入循环,打印'2',第三次调用next()拿到第三个字符'3' - 判断
'3'的done为false进入循环,打印'3',第四次调用next()拿到迭代结束标记{value: undefined, done: true} - 判断
done为true,退出循环
最终依次输出1、2、3,符合预期。
第二段仅输出"1"的代码执行逻辑
const str = '123'; const iterator = str[Symbol.iterator]() let charAt = iterator.next() while (!iterator.next().done) { console.log(charAt.value) charAt = iterator.next() }
这段代码每轮循环会调用两次next(),指针每次跳两位:
- 初始首次调用
next(),拿到第一个字符'1',存在charAt变量中 - 第一次循环判断:第二次调用
next()拿到第二个字符'2',done为false,条件成立进入循环 - 打印
charAt里存的'1',第三次调用next()拿到第三个字符'3',赋值给charAt - 第二次循环判断:第四次调用
next()直接拿到迭代结束标记,done为true,条件不成立,直接退出循环
最终只会输出一次'1'。
写迭代器循环的时候要记住:
next()调用一次就走一步,不要在非必要的地方重复调用。如果想把判断和赋值写在while条件里,可以写成while (!(charAt = iterator.next()).done)的形式,保证每轮只调用一次next(),就不会出问题。
内容的提问来源于stack exchange,提问作者SoF
相关产品推荐
相关产品推荐

