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

遍历日期可迭代对象结果异常的原因及解决方法问询

问题原因与解决办法

这个问题我之前踩过坑,核心根源是引用类型和原始类型的本质差异,咱们一步步说清楚:

为什么会出现全是最后一个日期的情况?

首先你要明白:Date是引用类型,而数字是原始类型。

在你的日期迭代器里,this.current指向的是同一个Date对象。每次调用next()时,你只是修改了这个对象内部的日期值,然后把这个对象的引用返回出去。当Array.from遍历迭代器时,它会把每次next()返回的value都存入数组,但这些value其实都是指向同一个Date对象的指针。等迭代结束时,这个唯一的Date对象已经被修改成了to之后的那一天,所以数组里所有元素看起来都是最后那个日期。

而对比数字迭代器的例子,current是原始类型(number),每次返回this.current++时,返回的是一个新的数值(原始类型的值是不可变的,每次自增都是生成新值),所以数组里的每个元素都是独立的,自然能得到正确的结果。

可行的替代方案

方案1:每次返回新的Date对象副本

修改next()方法,在返回前先创建当前日期的副本,再修改原current:

const dateRange = {
  from: new Date(2018, 0, 23),
  to: new Date(2018, 0, 28),
  [Symbol.iterator]() {
    this.current = new Date(this.from); // 初始化副本,避免修改原from
    return this;
  },
  next() {
    if (this.current <= this.to) {
      // 创建当前日期的副本,返回这个副本
      const currentDate = new Date(this.current);
      this.current.setDate(this.current.getDate() + 1);
      return {done: false, value: currentDate};
    }
    return {done: true};
  }
};

这样数组里的每个元素都是独立的Date对象,不会互相干扰。

方案2:让迭代器状态独立于原对象(推荐)

把迭代器的状态封装在单独的对象里,避免污染原dateRange的属性,同时支持多并发迭代:

const dateRange = {
  from: new Date(2018, 0, 23),
  to: new Date(2018, 0, 28),
  [Symbol.iterator]() {
    // 初始化独立的迭代状态,不修改原对象
    let current = new Date(this.from);
    const endDate = this.to;
    return {
      next() {
        if (current <= endDate) {
          const value = new Date(current);
          current.setDate(current.getDate() + 1);
          return {done: false, value};
        }
        return {done: true};
      }
    };
  }
};

这种写法的好处是,你可以同时用多个for...of遍历dateRange,它们的迭代状态不会互相影响,而原来的写法做不到这一点。

方案3:用生成器函数实现(最简洁)

ES6的生成器函数天生适合写迭代器,代码更简洁易懂:

const dateRange = {
  from: new Date(2018, 0, 23),
  to: new Date(2018, 0, 28),
  *[Symbol.iterator]() {
    let current = new Date(this.from);
    while (current <= this.to) {
      yield new Date(current); // 每次yield新的Date对象
      current.setDate(current.getDate() + 1);
    }
  }
};

生成器会自动处理迭代状态,每次yield的都是独立的Date对象,无论是Array.from转换还是for...of遍历,结果都完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:21:54