在循环中使用Moment.js出现异常结果问题求助
解决Moment.js循环生成时段出现重复值的问题
我看到你遇到了一个挺奇怪的问题:同样的Moment.js代码在不同环境下输出结果不一致,本地或playcode里得到重复的2020-03-09 11:00,但预期是11:00和11:30。让我来帮你分析原因并解决它:
问题根源:控制台对Moment对象的延迟解析
你遇到的这个现象大概率是控制台的“延迟求值”特性导致的视觉错觉,而非代码逻辑本身的问题。
当你直接打印Moment对象数组时,很多浏览器或在线编辑器的控制台不会立即解析对象的所有属性——而是等到你展开数组查看时才会读取对象的当前值。但你的startDate在循环中一直在被修改,虽然你用了clone()创建新对象,但某些环境下的控制台可能还是会出现显示异常(比如缓存了对象引用,导致展开时显示的是最终的startDate值)。
验证解决方案:格式化输出日期
你只需要把Moment对象转换成格式化后的字符串再打印,就能看到真实的结果了。修改你的console.log代码:
console.log(timeSlots.map(slot => slot.format('YYYY-MM-DD HH:mm')));
运行这段代码后,你应该会得到预期的["2020-03-09 11:00", "2020-03-09 11:30"]。
确认代码逻辑的正确性
其实你的核心逻辑是没问题的:
- 初始
startDate为11:00,第一次循环时endDate与startDate相差90分钟(≥60),推入克隆的11:00,然后startDate加30分钟变成11:30 - 第二次循环时两者相差60分钟(≥60),推入克隆的
11:30,然后startDate加30分钟变成12:00 - 第三次循环时两者相差30分钟(<60),退出循环
完全符合你预期的时段生成逻辑。
额外优化建议
如果你想避免这类控制台显示问题,也可以在推入数组时直接存储格式化后的字符串,而非Moment对象:
const timeSlots: string[] = []; let startDate = moment('2020-03-09 11:00'); let endDate = moment('2020-03-09 12:30'); while (endDate.diff(startDate, 'minutes') >= 60) { timeSlots.push(startDate.format('YYYY-MM-DD HH:mm')); startDate.add(30, 'minutes'); } console.log(timeSlots);
这样打印出来的就是直接的字符串数组,不会有任何显示歧义。
内容的提问来源于stack exchange,提问作者Antoine Grenard
相关产品推荐
相关产品推荐

