for (let i = 1; i <= n; i++) {
if (i % 15 === 0) 'FizzBuzz' // 必须最先判断:15 的倍数同时是 3 和 5 的倍数
else if (i % 3 === 0) 'Fizz'
else if (i % 5 === 0) 'Buzz'
else i 本身
}
把这些 if 写成平级(各自独立、不用 else)也不会「双重上色」,但用 else if 才能保证只命中第一个成立的分支——判断条件互斥时优先用 else if 或 switch。
const fruits = ['苹果', '香蕉', '橙子']
const user = { name: '阿蓝', age: 28 }
for (const v of fruits) { ... } // v 是值:'苹果' '香蕉' '橙子'
for (const i in fruits) { ... } // i 是下标,而且是字符串 '0' '1' '2'
for (const k in user) { ... } // k 是键名:'name' 'age'(遍历对象只能用 in)
规则记一条就够:数组和「可迭代对象」用 for...of,普通对象用 for...in(或 Object.entries())。对数组用 for...in 不仅拿到字符串下标,还会把挂在原型上的可枚举属性一起翻出来,是教科书级的错误写法。
// while:条件为假时,循环体一次都不执行
let n = 1234
const digits = []
while (n > 0) { digits.push(n % 10); n = Math.floor(n / 10) } // [4,3,2,1]
// do...while:至少执行一次,再判断要不要继续
let m = 0
do { log('执行了'); m++ } while (m > 0)
用途区分:while 适合「先把数字拆完 / 先把任务取完」这类可能为空的场景;do...while 适合「先做一次、再问要不要重复」的场景,比如菜单至少显示一次、重试至少发起一次。
for (let i = 1; i <= 60; i++) {
if (i % 3 === 0 && i % 5 === 1) { log('找到了:' + i); break } // 找到就跳出整个循环
}
for (let i = 1; i <= 20; i++) {
if (i % 2 !== 0) continue // 奇数跳过本轮,直接进入 i++
log(i)
}
switch (day) {
case 6:
case 7:
return '周末' // 有意穿透:6 与 7 共用同一段逻辑
case 5:
return '周五,马上放假'
default:
return '工作日'
}
// 没有 break 时不会退出,会继续往下执行所有 case:
// case 5: log('周五'); case 6: log('周六'); ... 一直穿透到结尾
规范写法:每个 case 结尾都写 break(或直接 return,在函数里更干净);只有「多个值共用一段逻辑」时才故意让 case 连续排列——比如 6 和 7 都落到「周末」。漏掉 default 则所有值都不匹配时什么也不做。switch 用的是严格相等 === 比较,字符串 '5' 不会命中数字 5。