跳到主要内容

错误处理

try/catch/finally 如何控制执行流?​

try {
window.someNonexistentFunction();
} catch (error) {
console.log(error.message);
} finally {
console.log("finally");
}
  • try: 代码出错时中断, 跳转到 catch;
  • catch: 接收包含错误信息的对象;
  • finally: 无论 try 还是 catch 执行, 最后都会执行;
  • 覆盖 return: 只要包含 finally, try/catch 中的 return 会被 finally 的返回值覆盖;
function f() {
try {
return 2;
} catch {
return 1;
} finally {
return 0; // 最终返回 0
}
}

window.onerror 捕获什么?​

  • 时机: 捕获没有被 try/catch 处理的错误;
  • 用法: 只能用 DOM0 写法, 回调依次收到错误信息、错误所在 URL 与行号;
  • 定位: 最后一道防线, 不建议作为主要错误处理手段;
window.onerror = (message, url, line) => {
console.log(message, url, line);
};

try...catch 能捕获哪类错误?​

  • 前提: 代码必须合法可运行; 只有运行期错误 (异常) 能捕获;
  • 解析期错误: 语法错误在引擎 "读代码" 阶段就发生, 那时 try 还没开始执行, 无法恢复;
  • 流程: try 无错则跳过 catch; 出错则 try 立即中断, 控制流转到 catch 开头, 错误对象作为参数传入;
  • 同步性: 只覆盖当前同步调用栈; setTimeout 里的错误要它自己的 try...catch 才能接住;
  • 省略绑定: 不需要错误细节时写 catch {, 不写 (err);
  • finally: 无论正常结束、return 还是出错都先执行, 与 return 的覆盖关系见本文第一节;
try {
setTimeout(() => noSuchVariable, 1000);
} catch {
/* 不会执行 */
}
setTimeout(() => {
try {
noSuchVariable;
} catch {
console.log("caught");
}
}, 1000);