副队长JavaScript教程(49)-主动抛出异常与错误类型

点此查看 所有教程、项目、源码导航

文章目录

  • [1. 背景](#1. 背景)
  • [2. throw 抛出异常](#2. throw 抛出异常)
    • [2.1 throw 的作用](#2.1 throw 的作用)
    • [2.2 基础示例](#2.2 基础示例)
    • [2.3 什么时候需要 throw](#2.3 什么时候需要 throw)
  • [3. JS 内置错误类型](#3. JS 内置错误类型)
    • [3.1 Error](#3.1 Error)
    • [3.2 ReferenceError 引用错误](#3.2 ReferenceError 引用错误)
    • [3.3 TypeError 类型错误](#3.3 TypeError 类型错误)
    • [3.4 RangeError 范围错误](#3.4 RangeError 范围错误)
  • [4. 异常处理常见坑](#4. 异常处理常见坑)
    • [4.1 不要无脑捕获所有异常](#4.1 不要无脑捕获所有异常)
    • [4.2 异常尽量就近捕获](#4.2 异常尽量就近捕获)
    • [4.3 区分:哪些错误抓不住](#4.3 区分:哪些错误抓不住)
  • [5. 综合小案例](#5. 综合小案例)
  • [6. 小结](#6. 小结)

1. 背景

上一篇我们学习了 try catch finally,用来捕获代码运行时自动产生的异常。

异常不只有 JS 引擎自动抛出这一种情况,在开发中,很多时候是我们自己判断业务逻辑,觉得当前数据不合法,需要主动抛出错误,提醒调用者。

本篇我们学习 throw 主动抛出异常,同时认识 JS 内置的几种错误类型,以及异常处理的编码规范。

2. throw 抛出异常

2.1 throw 的作用

throw 关键字可以让我们手动制造一个异常 。

一旦执行 throw,代码立刻中断,抛出的内容会被外层的 catch 捕获。

基础语法:

js 复制代码
throw 内容;

开发规范:尽量抛出错误对象,而不是直接抛出字符串、数字。

2.2 基础示例

js 复制代码
var age = 15;

if (age < 18) {
    throw new Error("年龄不足18岁,不允许访问");
}
console.log("验证通过");

直接运行这段代码,控制台会报错,后面的 console.log 不会执行。

如果外层包上 try-catch,就可以接住我们手动抛出的异常:

js 复制代码
var age = 15;
try {
    if (age < 18) {
        throw new Error("年龄不足18岁,不允许访问");
    }
    console.log("验证通过");
} catch (err) {
    console.log("捕获到自定义错误:", err.message);
}

2.3 什么时候需要 throw

当函数收到不符合预期的参数、条件不满足时,适合使用 throw。

函数只负责校验规则,出错的时候抛出异常,由调用方决定怎么处理这个错误。

js 复制代码
function getScore(score) {
    if (score < 0 || score > 100) {
        throw new Error("分数必须在0~100之间");
    }
    return score;
}

try {
    getScore(120);
} catch (err) {
    console.log(err.message);
}

3. JS 内置错误类型

我们前面一直用 new Error(),这是通用错误。

JS 还内置了几类细分的错误构造函数,用来区分不同种类的问题。

3.1 Error

通用错误类型,其他错误类型都继承自它。

不确定具体错误类型的时候,优先使用它。

js 复制代码
throw new Error("通用错误提示");

3.2 ReferenceError 引用错误

访问一个没有定义的变量时,引擎抛出的就是这个类型。

我们自己抛的时候,适合标记 "找不到变量 / 标识" 这类场景。

js 复制代码
throw new ReferenceError("该变量不存在");

3.3 TypeError 类型错误

变量的类型不符合预期,就适合用这个。

比如期待是数字,传进来却是字符串;期待是函数,传进来是对象。

js 复制代码
var num = "abc";
if (typeof num !== "number") {
    throw new TypeError("参数必须是数字类型");
}

3.4 RangeError 范围错误

数值超出合法范围时使用。

js 复制代码
function setCount(n) {
    if (n < 0) {
        throw new RangeError("数量不能是负数");
    }
}

补充:还有 SyntaxError 语法错误,这个是解析阶段产生的,代码没执行完就报错,try-catch 无法捕获,我们一般不会手动 throw 这个类型。

4. 异常处理常见坑

4.1 不要无脑捕获所有异常

不要为了程序不报错,随便给一大段代码套上 try-catch。

js 复制代码
// 不推荐
try {
    // 一大段很多逻辑
} catch (e) {}

空 catch 会悄悄吃掉所有错误,代码出问题的时候没有任何提示,调试非常困难。

4.2 异常尽量就近捕获

哪里容易出错,就在哪里加 try-catch,不要所有错误都堆在最外层统一捕获,不利于定位问题。

4.3 区分:哪些错误抓不住

语法错误(少写括号、少写分号、关键字写错)属于解析阶段错误,JS 还没开始执行代码,try-catch 不起作用。

try-catch 只能捕获运行时抛出的异常,包括引擎自动抛出、我们 throw 手动抛出的。

5. 综合小案例

结合 throw + try-catch + TypeError 写一个参数校验的示例:

js 复制代码
function calcArea(width, height) {
    if (typeof width !== "number" || typeof height !== "number") {
        throw new TypeError("宽和高必须是数字");
    }
    if (width <= 0 || height <= 0) {
        throw new RangeError("宽高必须大于0");
    }
    return width * height;
}

try {
    var res = calcArea(-10, 20);
    console.log("面积:", res);
} catch (err) {
    console.log("错误类型:", err.name);
    console.log("错误信息:", err.message);
}

6. 小结

  1. throw 用来主动抛出异常,中断代码执行,配合 try-catch 实现自定义错误提示;
  2. 推荐抛出错误对象 new Error(),不建议直接抛出字符串;
  3. 内置错误:Error、ReferenceError、TypeError、RangeError,不同场景选择对应的类型;
  4. 编码原则:不滥用 try-catch、禁止空 catch 吞掉错误、语法错误无法被捕获。
相关推荐
hhhjhl1 小时前
Protobuf.js 跨端三方库仓颉适配全流程
javascript·网络·udp
Flynt4 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
slongzhang_6 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
liyi_hz20088 小时前
O2OA(翱途) V10.1 即将发布|功能再升级,安全再加固,协同更高效!
java·javascript·windows·开源软件
志尊宝9 小时前
AI原生前端开发(029):AI辅助的文档自动生成
javascript·人工智能·ai-native
一个游离的指针10 小时前
ES6新特性:let、const、块级作用域
开发语言·javascript·es6
Hilaku10 小时前
删了一个没用的 console.log,生产环境直接崩了!
前端·javascript·程序员
真上帝的左手10 小时前
2. 编程语言-JavaScript
开发语言·javascript
2601_9498477511 小时前
Form-data 跨端三方库仓颉适配全流程
前端·javascript·flutter