为什么这个简单的 moment.js 逻辑会导致无限循环?
Why does this simple moment.js logic cause an infinite loop?
这段代码创建了一个无限循环。
|将 <=
更改为 <
不会创建无限循环。
var s_date = "2020-05-07";
var e_date = "2020-12-31";
for (
var i = 0;
Number(moment(s_date).add(i, "M").format("M")) <=
Number(moment(e_date).format("M"));
i++
) {
var month = moment(s_date).add(i, "M").format("MMM");
console.log(month, moment(e_date).format("MMM"));
}
输出:
May Dec
Jun Dec
Jul Dec
Aug Dec
Sep Dec
Oct Dec
Nov Dec
Dec Dec
Jan Dec
...
Number(moment(e_date).format("M"))
是 11.
Number(moment(s_date).add(i, "M").format("M"))
在 [0, 11] 范围内。
x <= 11
对 [0, 11] 中的所有 x
都成立。
Number(moment(s_date).add(i, "M").format("M")) <= Number(moment(e_date).format("M"))
总是正确的。
就像
for (let i = 0; (5 + i) % 12 <= 11; i++) // infinite loop
和
for (let i = 0; (5 + i) % 12 < 11; i++) // leaves loop for i == 6
更深层次的想法是,日期是数量,而格式化字符串不是,即使被强制转换为数字。使用diff
衡量数量差异,分解循环不变代码更高效可读
const s_date = "2020-05-07";
const e_date = "2020-12-31";
let mStart = moment(s_date);
let mEnd = moment(e_date);
for (
let mDate = mStart.clone();
mEnd.diff(mDate, "M") > 0;
mDate.add(1, "M")
) {
console.log(mDate.format("MMM"), mEnd.format("MMM"));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
这段代码创建了一个无限循环。
|将 <=
更改为 <
不会创建无限循环。
var s_date = "2020-05-07";
var e_date = "2020-12-31";
for (
var i = 0;
Number(moment(s_date).add(i, "M").format("M")) <=
Number(moment(e_date).format("M"));
i++
) {
var month = moment(s_date).add(i, "M").format("MMM");
console.log(month, moment(e_date).format("MMM"));
}
输出:
May Dec
Jun Dec
Jul Dec
Aug Dec
Sep Dec
Oct Dec
Nov Dec
Dec Dec
Jan Dec
...
Number(moment(e_date).format("M"))
是 11.
Number(moment(s_date).add(i, "M").format("M"))
在 [0, 11] 范围内。
x <= 11
对 [0, 11] 中的所有 x
都成立。
Number(moment(s_date).add(i, "M").format("M")) <= Number(moment(e_date).format("M"))
总是正确的。
就像
for (let i = 0; (5 + i) % 12 <= 11; i++) // infinite loop
和
for (let i = 0; (5 + i) % 12 < 11; i++) // leaves loop for i == 6
更深层次的想法是,日期是数量,而格式化字符串不是,即使被强制转换为数字。使用diff
衡量数量差异,分解循环不变代码更高效可读
const s_date = "2020-05-07";
const e_date = "2020-12-31";
let mStart = moment(s_date);
let mEnd = moment(e_date);
for (
let mDate = mStart.clone();
mEnd.diff(mDate, "M") > 0;
mDate.add(1, "M")
) {
console.log(mDate.format("MMM"), mEnd.format("MMM"));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>