写代码时,很多人以为只要语法没错,程序就能跑通。可现实是,程序跑得起来,不代表逻辑就对。尤其在业务复杂、分支众多的情况下,逻辑错误往往比语法错误更难排查,也更容易引发线上事故。
把“能运行”当成“正确”
新手常犯的一个错,就是看到程序输出了结果,就认为逻辑没问题。比如写个计算器,输入 2 + 2 得到 4,就觉得加法功能完成了。但一旦换成 0.1 + 0.2,结果却是 0.30000000000000004。这不是程序崩溃,而是浮点数精度问题导致的逻辑偏差。用户看到不对劲的结果,管你中间怎么算的?
忽略边界条件
很多逻辑漏洞藏在边界里。比如判断用户是否成年,写成 age >= 18 就放行。看起来没问题,但如果 age 是负数呢?或者是个空值?系统直接崩了,或者让用户钻了空子。再比如处理数组遍历时,习惯写 for (int i = 0; i < arr.length; i++),但如果数组为空,或者被中途修改了长度,循环可能跳不过去或越界。
误用布尔表达式
逻辑运算符看着简单,一组合起来就容易出错。比如想表达“不是管理员且未登录就不能访问”,写成 if (!isAdmin && !isLoggedIn) deny()。可如果实际需求是“只要不是管理员,即使登录了也不行”,那这个条件就不够。更糟的是混用 || 和 && 时不加括号,优先级一乱,结果完全偏离预期。
if (user.type == 'guest' || user.level < 3 && !user.premium)
showAds();
这段代码本意是给普通用户和非高级会员推广告,但由于 && 优先级高于 ||,实际执行可能是先算后面再或前面,导致部分高级会员也被推送。加上括号才保险:
if ((user.type == 'guest' || user.level < 3) && !user.premium)
showAds();
状态管理混乱
在前端开发中,组件状态更新不同步很常见。比如一个表单提交后,按钮置为禁用状态 loading=true,请求结束再恢复。但如果网络异常,回调没触发,按钮就一直卡住。用户刷新页面前,再也无法操作。类似情况还出现在开关控制、权限切换等场景,状态没闭环,用户就懵了。
过度依赖顺序执行
有些程序员习惯按“步骤”写代码,认为上一步执行完,下一步自然会按预期进行。比如先读文件,再解析内容,最后保存数据库。但如果文件不存在,解析那步就会报错。更隐蔽的是异步操作,比如发两个请求,指望第二个等第一个回来再发,结果因为没加 await 或回调嵌套出错,数据错乱。
复制粘贴带来的逻辑残留
赶工期时,复制一段能用的代码改改变量名,是最省事的做法。可问题在于,旧代码里的判断条件、默认值、异常处理可能根本不适用于新场景。比如从用户注册逻辑复制到商家入驻,忘了改校验规则,结果手机号格式不对也能提交。这种“看似一样,实则不同”的地方,最容易埋雷。
把调试输出当最终验证
打印一堆 console.log 看变量值,确实能帮人理清流程。但有些人只看日志输出符合预期,就认为逻辑正确。问题是,日志只反映当前路径,换一组输入可能就走不通。真正可靠的验证是单元测试覆盖各种情况,而不是靠肉眼扫几行输出。