网站

JavaScript 错误处理

try…catch | MDN

Error | MDN

引入

JS 代码运行时不一定总是顺利。

如果变量写错、接口请求失败、用户输入不合法,都可能让代码报错。错误处理就是用来避免程序直接崩掉,并给出更合适的处理方式。

正文

定义

定义

JS 错误处理用于捕获和处理代码运行中的异常,常见写法是 try…catchthrowfinally

简单理解:

有些代码可能会出问题,可以先把它放进 try 里执行。

如果出错,就进入 catch,在里面处理错误。

如果有无论成功还是失败都要执行的代码,可以写在 finally 里。

基础语法

try {
  // 可能出错的代码
} catch (error) {
  // 出错后的处理
} finally {
  // 无论是否出错都会执行
}

最常见写法:

try {
  console.log(user.name);
} catch (error) {
  console.log("代码出错了");
  console.log(error.message);
}

这里如果 user 没有定义,代码不会直接中断整个程序,而是进入 catch

try

try 用来包住可能会出错的代码。

try {
  let result = JSON.parse("错误的 JSON 字符串");
  console.log(result);
} catch (error) {
  console.log("JSON 解析失败");
}

JSON.parse() 要求字符串必须是合法 JSON。

如果字符串格式不对,就会报错。

把它放到 try 里,就可以用 catch 接住这个错误。

catch

catch 用来处理 try 中出现的错误。

try {
  console.log(title);
} catch (error) {
  console.log(error.name);
  console.log(error.message);
}

catch 中的 error 是错误对象。

常见属性:

属性作用
error.name错误名称
error.message错误提示信息
error.stack错误调用位置,常用于调试

学习阶段最常用的是 error.message

finally

finally 中的代码无论是否出错都会执行。

try {
  console.log("开始执行");
} catch (error) {
  console.log("出错了");
} finally {
  console.log("执行结束");
}

finally 常用于收尾操作。

例如关闭加载状态、清理临时数据、恢复按钮状态等。

let loading = true;
 
try {
  console.log("请求数据");
} catch (error) {
  console.log("请求失败");
} finally {
  loading = false;
}

这里不管请求成功还是失败,最后都会把 loading 改成 false

throw

throw 用于主动抛出错误。

不是所有错误都必须等 JS 自动报错,有时候可以根据业务规则自己抛出错误

function checkAge(age) {
  if (age < 18) {
    throw new Error("年龄不能小于 18 岁");
  }
 
  return "验证通过";
}

调用时可以用 try…catch 捕获。

try {
  const result = checkAge(16);
  console.log(result);
} catch (error) {
  console.log(error.message);
}

这个例子中,age 小于 18 时会主动抛出错误。

catch 捕获到错误后,会输出错误信息。

Error 对象

Error 是 JS 中常见的错误对象。

const error = new Error("这是一个错误");
 
console.log(error.message);

主动抛出错误时,常见写法是:

throw new Error("错误说明");

这样比直接 throw "错误说明"; 更规范。

因为 Error 对象会带有更多错误信息,调试时更方便。

常见错误类型

错误类型常见原因
ReferenceError使用了不存在的变量
TypeError数据类型不对,或者访问了不能访问的属性和方法
SyntaxError语法写错
RangeError数值超出允许范围
URIErrorURI 编码或解码出错

ReferenceError

ReferenceError 通常是变量没有定义。

console.log(userName);

如果 userName 没有声明,就会报 ReferenceError

常见原因:

  • 变量名写错
  • 大小写写错
  • 在变量声明之前使用变量
  • 变量作用域不对

TypeError

TypeError 通常是数据类型不符合预期。

const user = null;
 
console.log(user.name);

这里 usernull,不能继续访问 .name,所以会报错。

常见原因:

  • nullundefined 读取属性
  • 把不是函数的值当函数调用
  • 数据结构和预期不一致

SyntaxError

SyntaxError 是语法错误。

if (true {
  console.log("hello");
}

这里少了一个 ),代码语法不完整。

语法错误通常会让代码无法正常执行。

这种错误要先检查括号、引号、逗号、分号、代码块是否写完整。

例子

捕获 JSON 解析错误

const text = "{name: 'Tom'}";
 
try {
  const data = JSON.parse(text);
  console.log(data);
} catch (error) {
  console.log("数据格式不正确");
}

JSON.parse() 只能解析合法 JSON。

上面的字符串格式不符合 JSON 规则,所以会进入 catch

正确 JSON 字符串中的属性名和字符串值都需要使用双引号。

const text = '{"name": "Tom"}';

表单输入校验

function checkName(name) {
  if (!name) {
    throw new Error("用户名不能为空");
  }
 
  return name;
}
 
try {
  const name = checkName("");
  console.log(name);
} catch (error) {
  console.log(error.message);
}

这个例子中,空字符串不符合要求,所以主动抛出错误。

catch 负责把错误信息显示或记录下来。

请求失败时处理错误

async function loadUser() {
  try {
    const response = await fetch("/api/user");
    const data = await response.json();
 
    console.log(data);
  } catch (error) {
    console.log("用户信息加载失败");
  }
}

异步请求中也经常使用 try…catch

它可以捕获网络请求、数据解析等过程中的错误。

常见写法

写法作用
try {}包住可能出错的代码
catch (error) {}捕获并处理错误
finally {}无论是否出错都会执行
throw主动抛出错误
new Error()创建错误对象
error.message获取错误提示信息

特点

  • try 中放可能出错的代码
  • catch 中处理错误,避免程序直接中断
  • finally 中放收尾代码
  • throw 可以主动抛出错误
  • new Error() 可以创建更规范的错误对象
  • 错误处理不是为了隐藏错误,而是为了让程序更稳定、更容易调试

注意事项

  • 不要把所有代码都随便包进一个很大的 try…catch
  • catch 里不要什么都不写,否则错误会被悄悄吞掉
  • 捕获错误后,至少要记录 error.message 或给用户提示
  • try…catch 主要捕获运行时错误,语法错误通常要先修正代码
  • 异步代码中,async…await 可以配合 try…catch 使用
  • Promise 链式写法中,也可以用 .catch() 处理错误

理解

可以把错误处理理解为给代码准备一个“出错后的备用方案”。

没有错误处理时,代码一旦出错,后面的逻辑可能就不执行了。

有了 try…catch,就可以在出错时进入 catch,给出提示、记录日志,或者让页面保持可用。

但错误处理不是把错误藏起来,而是让错误更容易被发现和处理。

引出

理解错误处理之后,可以继续学习 JS PromiseJS async await,因为异步请求中经常需要处理失败情况。