JavaScript 中有哪些错误类型?如何正确处理异常?

JavaScript 内置错误类型

Error                  — 基类
├── SyntaxError        — 语法错误
├── ReferenceError     — 引用不存在的变量
├── TypeError          — 类型错误
├── RangeError         — 值超出有效范围
├── URIError           — URI 编解码错误
├── EvalError          — eval 相关(已废弃)
└── AggregateError     — 多个错误聚合(ES2021)
console.log(a)         // ReferenceError: a is not defined
null.foo()              // TypeError: Cannot read properties of null
new Array(-1)           // RangeError: Invalid array length
decodeURIComponent('%') // URIError: URI malformed

异常处理

try {
  // 可能出错的代码
  JSON.parse(invalidJson)
} catch (error) {
  // 捕获错误
  console.error(error.message)
  console.error(error.stack)
} finally {
  // 无论是否出错都执行
  cleanup()
}

自定义错误

class ValidationError extends Error {
  constructor(message, field) {
    super(message)
    this.name = 'ValidationError'
    this.field = field
  }
}

function validateUser(user) {
  if (!user.email) {
    throw new ValidationError('邮箱不能为空', 'email')
  }
}

Promise 错误处理

// .catch 捕获
fetch('/api')
  .then(res => res.json())
  .catch(err => console.error('请求失败:', err))

// async/await + try/catch
async function fetchData() {
  try {
    const res = await fetch('/api')
    return await res.json()
  } catch (err) {
    console.error('请求失败:', err)
    // 可以选择重试或返回默认值
    return null
  }
}

全局错误捕获

// 同步错误
window.onerror = (message, source, lineno, colno, error) => {
  console.error('全局错误:', error)
}

// Promise 未捕获的 rejection
window.addEventListener('unhandledrejection', (event) => {
  console.error('未处理的 Promise 拒绝:', event.reason)
})

最佳实践

  1. 不要吞掉错误:catch 中至少要有日志
  2. 区分错误类型:自定义错误类便于分类处理
  3. 优雅降级:出错时返回默认值或显示友好提示
  4. 异步错误必须处理:Promise 链必须有 catch

同分类其他题目