讲解

编程一半的时间在调试。最基础的武器是 console 家族:console.log 打值,console.warn/error 分级提示,console.table 把数组和对象打成表格(查看列表数据远比 log 清晰),console.time('标签') 配合 console.timeEnd('标签') 测量耗时,console.group 折叠分组,console.trace 打印调用栈。会灵活组合这些,八成的问题不用打开调试器。

浏览器开发者工具的 Sources 面板是重型武器:给某行代码打断点(点行号,或在代码里写 debugger 语句),执行到那里会暂停,可以逐行步进(F10 跳过函数、F11 进入函数),查看当前作用域所有变量的实时值,在 Watch 里监视表达式,在 Call Stack 里回溯调用链。比起盲猜式 log 调试,断点调试能回答「此刻程序里到底发生了什么」。

排错的方法论比工具更重要:一、读错误信息——报错行号、错误类型、堆栈顺序,大多数错误信息直接告诉你答案;二、最小复现——把无关代码砍掉,用最小输入重现问题,范围缩小一半答案就近了一半;三、二分定位——在可疑区间中段打印或打断点,每次排除一半;四、假设验证——明确说出「我认为这里应该是 X」,再用证据推翻或证实,避免漫无目的地改代码碰运气。改一处、跑一遍、看结果,小步快走。

示例

// console.table:结构化数据一目了然
const users = [
  { name: '小明', score: 88 },
  { name: '小红', score: 95 },
  { name: '小刚', score: 61 },
];
console.table(users);

// console.time:测量一段代码耗时
console.time('排序耗时');
const arr = Array.from({ length: 10000 }, () => Math.random());
arr.sort((a, b) => a - b);
console.timeEnd('排序耗时');

// 分级输出
console.log('普通信息');
console.warn('警告:配置项缺失,使用默认值');
console.error('错误:数据加载失败');

// 用断言快速验证假设
const total = users.reduce((acc, u) => acc + u.score, 0);
console.assert(total > 0, '总分不应为 0');
console.log('假设成立,总分:', total);

// 二分定位的雏形:在可疑点打印中间状态
function calcDiscount(price, level) {
  const rate = level === 'vip' ? 0.8 : 1;
  console.log('中间状态 rate =', rate); // 假设出问题时,先看中间值
  const result = price * rate;
  console.log('中间状态 result =', result);
  return Math.round(result * 100) / 100;
}
console.log('折后价:', calcDiscount(199.99, 'vip'));

浏览器断点调试示意:

function processOrder(order) {
  debugger; // 打开 DevTools 时,执行到这里会暂停
  const total = order.items.reduce((sum, item) => sum + item.price * item.count, 0);
  return { ...order, total };
}

常见坑

  • log 打印对象后看到「后来」的值:控制台里的对象引用是活的,展开时显示的是当前状态而非打印时刻。需要快照用 console.log(JSON.parse(JSON.stringify(obj))) 或 structuredClone。
  • console.log 留在生产代码:调试完记得清理,或至少用 warn/error 之外的手段区分;满屏 log 既难看也轻微影响性能。
  • 改代码不看效果:连改五处再运行,出错时不知道是哪处引入的。小步修改、立即验证。
  • 只看报错的第一行:错误堆栈从下往上读是调用路径,真正的根因往往在堆栈深处你自己的代码里,而非顶层的库代码。

小结

console 家族覆盖日常调试,断点 + 步进回答「程序此刻的状态」;方法论上读报错、最小复现、二分定位、假设验证。下一章汇总一路走来的最佳实践。