刷题过程中同一个逻辑常有多种写法,这里记录我的首选方式和理由。后续持续补充。
数组遍历
首选:for...of
for (const item of arr) { ... }
简洁、可读,支持 break / continue。需要索引时用 entries():
for (const [i, item] of arr.entries()) { ... }
不选的方式:
forEach— 无法break/continue,回调里return只跳出当前迭代,容易踩坑for (let i = 0; ...)— 大多数场景不需要手动管理索引,写起来啰嗦;需要倒序或跳步时再用for...in— 遍历的是 key(字符串),还会遍历原型链属性,不该用在数组上
对象遍历
首选:Object.entries + for...of
for (const [key, value] of Object.entries(obj)) { ... }
同时拿到 key 和 value,配合解构很直观。只需要 key 或 value 时用 Object.keys() / Object.values()。
不选的方式:
for...in— 会遍历原型链上的属性,需要额外hasOwnProperty判断,麻烦且易遗漏Object.getOwnPropertyNames()— 会包含不可枚举属性,刷题用不上,过重Reflect.ownKeys()— 还会包含 Symbol 类型的 key,刷题场景完全不需要
数组创建
首选:Array.from
Array.from({ length: n }, () => 0)
Array.from({ length: n }, (_, i) => i)
一步到位创建并初始化,语义清晰。
不选的方式:
new Array(n).fill(0)— 填充基本类型没问题,但fill([])/fill({})会让所有元素共享同一个引用,是经典 bug[...Array(n)].map(...)— 先展开再 map,多了一步,可读性不如Array.from
计数兜底
首选:|| 0
map.set(key, (map.get(key) || 0) + 1)
obj[key] = (obj[key] || 0) + 1
简短直接,刷题够用。
不选的方式:
?? 0— 语义上更精确(只处理null/undefined),但刷题中计数值不会是false或"",||更短更顺手- 提前初始化所有 key 为 0 — 多一步遍历,刷题没必要
字符计算
首选:charCodeAt 后做数学运算
const idx = s.charCodeAt(i) - 97 // 'a' -> 0
直接得到数字,方便用作数组索引或做差值比较。
不选的方式:
- 字符直接加减(
s[i] - 'a')— JS 里字符串不能直接做算术运算,'b' - 'a'虽然返回1(隐式转换为 NaN?不,实际上 JS 里这会返回 NaN),必须用charCodeAt