You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(),迭代器指针逐位推进:

  1. 初始首次调用next(),拿到第一个字符'1',判断done为false进入循环
  2. 打印'1',第二次调用next()拿到第二个字符'2'
  3. 判断'2'的done为false进入循环,打印'2',第三次调用next()拿到第三个字符'3'
  4. 判断'3'的done为false进入循环,打印'3',第四次调用next()拿到迭代结束标记{value: undefined, done: true}
  5. 判断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(),指针每次跳两位:

  1. 初始首次调用next(),拿到第一个字符'1',存在charAt变量中
  2. 第一次循环判断:第二次调用next()拿到第二个字符'2',done为false,条件成立进入循环
  3. 打印charAt里存的'1',第三次调用next()拿到第三个字符'3',赋值给charAt
  4. 第二次循环判断:第四次调用next()直接拿到迭代结束标记,done为true,条件不成立,直接退出循环
    最终只会输出一次'1'。

写迭代器循环的时候要记住:next()调用一次就走一步,不要在非必要的地方重复调用。如果想把判断和赋值写在while条件里,可以写成while (!(charAt = iterator.next()).done)的形式,保证每轮只调用一次next(),就不会出问题。

内容的提问来源于stack exchange,提问作者SoF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 13:54:21