Skip to content

错误处理(避免代码崩溃)

19.1 常见错误类型

在 JavaScript 中,常见的错误类型有:

1. 语法错误(SyntaxError)

语法错误是由于代码语法不正确导致的错误。

javascript
// 缺少括号
if (true {
  console.log("Hello");
}
// 语法错误:Unexpected token '{'

// 缺少分号(在某些情况下可能不会报错,但最好加上)
const x = 1
const y = 2
// 可能会报错:Unexpected identifier

2. 引用错误(ReferenceError)

引用错误是由于引用了不存在的变量或函数导致的错误。

javascript
console.log(undefinedVariable);
// 引用错误:undefinedVariable is not defined

function foo() {
  console.log(bar);
}
foo();
// 引用错误:bar is not defined

3. 类型错误(TypeError)

类型错误是由于操作了错误类型的对象导致的错误。

javascript
const x = 10;
x();
// 类型错误:x is not a function

const obj = null;
console.log(obj.name);
// 类型错误:Cannot read property 'name' of null

const arr = [1, 2, 3];
arr.push(4).push(5);
// 类型错误:Cannot read property 'push' of undefined

4. 范围错误(RangeError)

范围错误是由于数值超出了有效范围导致的错误。

javascript
const arr = new Array(-1);
// 范围错误:Invalid array length

function factorial(n) {
  if (n < 0) {
    throw new RangeError("参数不能为负数");
  }
  // 计算阶乘
}
factorial(-1);
// 范围错误:参数不能为负数

5. URI 错误(URIError)

URI 错误是由于 URI 相关的操作导致的错误。

javascript
decodeURIComponent("%");
// URI 错误:URI malformed

19.2 try...catch 捕获错误

try...catch 语句用于捕获和处理错误,防止错误导致整个程序崩溃。

基本语法

javascript
try {
  // 可能会出错的代码
} catch (error) {
  // 处理错误的代码
  console.error(error);
}

示例:捕获类型错误

javascript
try {
  const obj = null;
  console.log(obj.name);
} catch (error) {
  console.error("发生错误:", error.message);
  // 发生错误:Cannot read property 'name' of null
}

console.log("程序继续执行");
// 程序继续执行

示例:捕获引用错误

javascript
try {
  console.log(undefinedVariable);
} catch (error) {
  console.error("错误类型:", error.name);
  console.error("错误信息:", error.message);
  // 错误类型:ReferenceError
  // 错误信息:undefinedVariable is not defined
}

finally 子句

finally 子句中的代码无论是否发生错误都会执行。

javascript
try {
  console.log("尝试执行代码");
  throw new Error("故意抛出错误");
} catch (error) {
  console.error("捕获到错误:", error.message);
} finally {
  console.log("无论是否出错都会执行的代码");
}

// 输出:
// 尝试执行代码
// 捕获到错误:故意抛出错误
// 无论是否出错都会执行的代码

抛出错误

使用 throw 语句可以手动抛出错误。

javascript
function divide(a, b) {
  if (b === 0) {
    throw new Error("除数不能为零");
  }
  return a / b;
}

try {
  const result = divide(10, 0);
  console.log("结果:", result);
} catch (error) {
  console.error("错误:", error.message);
  // 错误:除数不能为零
}

自定义错误类型

可以通过继承 Error 类来创建自定义错误类型。

javascript
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

function validateEmail(email) {
  if (!email.includes("@")) {
    throw new ValidationError("邮箱格式不正确");
  }
  return true;
}

try {
  validateEmail("invalid-email");
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("验证错误:", error.message);
  } else {
    console.error("其他错误:", error.message);
  }
}

19.3 调试技巧:控制台断点调试

使用控制台输出调试

javascript
function calculateTotal(prices) {
  console.log("开始计算总价格");
  console.log(" prices:", prices);
  
  let total = 0;
  for (let i = 0; i < prices.length; i++) {
    console.log(`处理第 ${i} 个价格:`, prices[i]);
    total += prices[i];
    console.log("当前总价格:", total);
  }
  
  console.log("计算完成,总价格:", total);
  return total;
}

const prices = [10, 20, 30];
const result = calculateTotal(prices);
console.log("最终结果:", result);

使用断点调试

  1. 在浏览器中设置断点

    • 打开浏览器的开发者工具(F12)
    • 切换到 "Sources" 或 "源代码" 标签
    • 找到要调试的 JavaScript 文件
    • 点击行号左侧设置断点
    • 刷新页面,代码会在断点处暂停
  2. 在 VS Code 中设置断点

    • 打开要调试的 JavaScript 文件
    • 点击行号左侧设置断点
    • 启动调试模式(F5)
    • 代码会在断点处暂停

断点调试时的操作

  • 继续执行:继续执行代码直到下一个断点
  • 单步执行:执行下一行代码
  • 步入:进入函数内部
  • 步出:从函数内部跳出
  • 查看变量:在调试面板中查看变量的值
  • 修改变量:在调试过程中修改变量的值

示例:使用断点调试函数

javascript
function factorial(n) {
  if (n === 0 || n === 1) {
    return 1;
  }
  return n * factorial(n - 1);
}

const result = factorial(5);
console.log("结果:", result);

实战:错误处理综合示例

javascript
// 模拟 API 调用
function fetchData(url) {
  return new Promise((resolve, reject) => {
    // 模拟网络延迟
    setTimeout(() => {
      // 模拟网络错误
      if (url.includes("error")) {
        reject(new Error("网络请求失败"));
      } else {
        resolve({ data: "成功获取数据", url });
      }
    }, 1000);
  });
}

// 处理 API 调用
async function processData(urls) {
  const results = [];
  
  for (const url of urls) {
    try {
      console.log(`开始请求: ${url}`);
      const data = await fetchData(url);
      results.push(data);
      console.log(`请求成功: ${url}`);
    } catch (error) {
      console.error(`请求失败: ${url}`, error.message);
      // 可以选择将错误也添加到结果中,或者跳过错误继续执行
      results.push({ error: error.message, url });
    } finally {
      console.log(`请求处理完成: ${url}`);
    }
  }
  
  return results;
}

// 测试
const urls = [
  "https://api.example.com/data1",
  "https://api.example.com/error",
  "https://api.example.com/data2"
];

processData(urls)
  .then(results => {
    console.log("所有请求处理完成");
    console.log("结果:", results);
  })
  .catch(error => {
    console.error("处理过程中发生错误:", error);
  });

小结

  • 常见的错误类型:语法错误、引用错误、类型错误、范围错误、URI 错误
  • 使用 try...catch 语句捕获和处理错误
  • 使用 finally 子句执行无论是否出错都需要执行的代码
  • 使用 throw 语句手动抛出错误
  • 可以通过继承 Error 类创建自定义错误类型
  • 调试技巧:
    • 使用 console.log() 输出调试信息
    • 在浏览器或 IDE 中设置断点进行调试
    • 查看和修改变量的值
  • 错误处理是编写健壮代码的重要部分,可以防止程序因错误而崩溃,提高用户体验

© 2026 编程马·菜鸟教程 版权所有