CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
JavaScript 核心/课时/错误处理与调试
RawBlame
课时目录12 节

JavaScript 核心

  1. 01JavaScript 是什么
  2. 02类型与变量
  3. 03运算符与类型转换
  4. 04条件与循环
  5. 05函数与作用域
  6. 06数组与常用方法
  7. 07对象与 JSON
  8. 08DOM 与事件
  9. 09异步 Promise 与 async/await
  10. 10ES Module 与 npm 概览
  11. 11错误处理与调试
  12. 12综合练习与下一步

错误处理与调试

try/catch、console、DevTools。

25 分钟

错误处理与调试

这一课你将能做到

  1. 读懂控制台报错的「哪一文件、哪一行」,并据此定位问题
  2. 用 try/catch 接住可能失败的代码并给用户提示
  3. 用断点或 console.log 做一次最小排查,形成固定套路

为什么要学

写 JS 一定会报错。
差别在于:有人看红字 10 秒定位;有人盲目改三小时。
调试是技能,不是丢脸。

真实项目里,网络失败、空数据、选择器写错每天都在发生。
会处理错误,你的小工具才配叫「能给别人用」。

先建立图像

出错 → 控制台红色堆栈(stack)
第一行通常最重要:错误类型 + 消息 + 位置
往下看:调用链(谁调用了谁)

常见类型:

名字人话例子
SyntaxError语法写破(缺括号、缺引号)——往往文件直接无法运行
TypeError对 null/undefined 取属性;不是函数却当函数调用
ReferenceError变量未定义就用
RangeError如错误的数组长度等少见场景
排查套路:
  1) 读红字第一行
  2) 用 log/断点验证「你以为的值」
  3) 一次只改一处
  4) 需要给用户退路时再包 try/catch

跟着做

步骤 1:故意报错并阅读堆栈

控制台:

const user = null;
user.name; // TypeError: Cannot read properties of null

应看到 TypeError,并指出行号。点开位置,确认「就是这一行」。
再试:

notDefinedNow; // ReferenceError

分清:没声明的名字 vs 有名字但是 null。

步骤 2:try/catch 给退路

function safeName(user) {
  try {
    return user.name.toUpperCase();
  } catch (err) {
    // 不要空 catch:至少留下日志
    console.error("safeName 失败", err);
    return "未知用户";
  }
}
console.log(safeName(null)); // 未知用户
console.log(safeName({ name: "ada" })); // ADA

人话:可能炸的地方包起来;失败时给退路,并留下日志。
但不要用 try/catch 掩盖「本该先校验」的逻辑——能提前 if (!user) 更清晰。

步骤 3:页面里的排查套路

保存为 js-errors.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>调试</title>
</head>
<body>
  <button type="button" id="btn">跑一下</button>
  <p id="out">等待操作</p>
  <script>
    document.getElementById("btn").addEventListener("click", function () {
      const el = document.getElementById("not-exist");
      console.log("el 是", el); // 先验证假设:这里多半是 null
      const out = document.getElementById("out");
      try {
        el.textContent = "hi"; // el 为 null 时会 TypeError
      } catch (err) {
        console.error(err);
        out.textContent = "找不到目标元素,请检查 id";
      }
    });
  </script>
</body>
</html>

正确修复方向:先判断 if (!el) { ...; return; },而不是永远靠 catch。
调试步骤:报错前加 console.log,确认假设。

步骤 4:断点(Sources)

  1. F12 → Sources / 源代码
  2. 打开你的文件 → 在可疑行号左侧点一下,出现蓝/红断点
  3. 再点击页面按钮

程序会在此暂停,右侧可看变量当前值。
按 Step / Resume 单步或继续。比狂打 log 更强,适合「值到底怎么变」的问题。

步骤 5:异步错误也要接住

async function load() {
  try {
    const res = await fetch("/this-will-fail-demo");
    if (!res.ok) throw new Error("HTTP " + res.status);
    return await res.text();
  } catch (err) {
    console.error("load 失败", err);
    throw err; // 需要时继续往外抛,让 UI 层提示
  }
}

load().catch(function (err) {
  // 防止未处理的 Promise 拒绝
  document.getElementById("out").textContent = "加载失败:" + err.message;
});

async 里用 try/catch 包住 await;若函数继续抛出,调用方还可用 .catch。

步骤 6:最小复现习惯

当你卡住时,新建一个临时 HTML,只保留:

<button type="button" id="btn">test</button>
<script>
  // 只留仍能坏的最小代码
  document.getElementById("btn").addEventListener("click", function () {
    console.log("clicked");
  });
</script>

能复现 → 问题边界清楚,好自查也好提问。
不能复现 → 说明问题在你删掉的那部分交互里,继续缩小范围。

讲清楚要点

  1. 因为堆栈第一行通常指向直接出错处,所以先读红字再改代码。
  2. 因为空 catch 会制造「问题消失」的假象,所以至少 console.error,并给用户提示。
  3. 因为用户输错与程序写错不同,所以输入非法要提示;代码写错要修,别混成一类。
  4. 因为一次改 20 处无法归因,所以小步修改、每次验证。
  5. 因为异步错误不会自动变成同步异常,所以 await 要配 try/catch 或 Promise .catch。
  6. 因为假设常常是错的,所以用 log/断点验证「元素是不是 null、值到底是什么」。

你可能会懵的地方

  • 异步错误
    async 里要用 try/catch 包住 await;只写同步 try 包不住后面的 Promise 拒绝。

  • 有时堆栈很长
    从最上面「你自己的文件」看起,库/框架文件先略读。

  • Source Map
    打包后行号可能对应源码映射;开发模式通常较直观。行号对不上时先确认是否看了编译后的文件。

  • 要不要到处 try/catch?
    不要。边界(网络、解析、用户输入)适合接;内部逻辑错误应尽早暴露,方便修。

错法对照

错法问题正解
无视红字浪费时间先读第一行与行号
空 catch问题消失假象记录并提示
一次改 20 处不知哪处生效小步修改
用 try/catch 代替空值判断控制流变糊能 if (!el) 就先判断
只在成功路径测上线才炸故意制造失败路径看提示

自测三问

  1. 看到 TypeError 读属性,你首先怀疑什么?
  2. try/catch 的职责边界是什么?什么情况更适合提前 if?
  3. 什么叫最小复现?它如何帮助调试?

小结一句话

报错是老师;读堆栈、打日志/断点、小步修复,再用 try/catch 在边界给用户留退路。

延伸

  • MDN:错误处理
  • MDN:调试 JavaScript
  • 下一课:综合练习——串起来做小工具。
加载本节练习…
← 上一课ES Module 与 npm 概览下一课 →综合练习与下一步