先读错误,再动手改
多数 JS 报错已经给出了位置和原因。TypeError: Cannot read properties of undefined 往往指向某个对象在访问属性前没有赋值;ReferenceError 多是变量作用域或拼写问题。打开控制台时先看堆栈最上面一帧,那是错误发生的真实位置,而不是外层调用位置。
把报错信息当作线索而非噪音,能避免大量无效修改。遇到压缩后的代码,启用 Source Map 还原可读堆栈,定位效率会明显提升。
断点比 console.log 更可控
console.log 适合快速确认,但输出多了会污染控制台,也难以观察变量在时间上的变化。Sources 面板的断点能暂停执行,逐行查看作用域中的变量。
常用三类断点:
- 行断点:在可疑代码行暂停,配合单步执行观察状态流转。
- 条件断点:只在条件成立时暂停,适合循环中定位特定一轮。
- DOM 断点:节点被修改或删除时触发,排查界面异常很直接。
调试时善用 Watch 面板固定关注几个变量,比反复打印更清晰。
异步问题要看调用链
回调、Promise、async/await 混用时,错误堆栈容易被截断。此时可在 Network 或 Performance 面板观察请求时序,确认是数据未返回还是回调顺序有误。Chrome DevTools 的 Async 调用栈选项能展开异步链路,帮助找到真正发起调用的位置。
未捕获的 Promise 拒绝不会自动抛出到全局,记得监听 unhandledrejection,否则错误会被静默吞掉。
性能瓶颈靠采样而非感觉
页面卡顿先别改代码,用 Performance 面板录制一段操作,看长任务出现在哪一帧。主线程被长时间占用的函数、频繁的强制同步布局、过大的重渲染,都会在火焰图中显现。
排查内存问题可借助 Memory 面板对比堆快照,确认对象是否被意外持有。定位到具体函数后再优化,比盲目加缓存更有效。
把调试变成习惯
调试的核心是缩小范围:先确认问题出在数据、逻辑还是渲染,再用断点和日志逐层排除。写代码时保留必要的错误边界和日志上下文,未来排查会省下不少时间。