# 异常处理机制

# 课程目标

  • 学习 JavaScript 几种常见的错误类型,并且了解导致这些错误的原因
  • 掌握错误处理机制,灵活运用 try/catch,throw ,根据实际开发场景自定义错误并且捕获异常进行相应处理,编写出可维护的代码

# 常见错误类型

错误是一种内置于 JS 语言的对象类型,由名称/类型和消息组成。错误包含重要信息,可帮助您定位导致错误的代码、确定出现此错误的原因以及解决错误。

代码执行过程中会发生各种各样的错误,现在让我们来看看几种常见的错误类型

# SyntaxError

当您尝试运行的代码不符合 JavaScript 的语法规则时,就会发生语法错误。例如这个:

let arr = 2b

将抛出以下错误,因为我们忘记给字符串添加引号了,不符合 JavaScript 语法规则。

错误屏幕截图 (opens new window)

参考SyntaxError - JavaScript | MDN (opens new window)

# ReferecnceError

ReferecnceError 错误会在找不到对象时发生,例如这个:

console.log(a)

将抛出以下错误,因为我们还没有定义 a 这个变量,导致找不到 a 这个变量.

错误屏幕截图 (opens new window)

参考ReferenceError - JavaScript | MDN (opens new window)

# TypeError

TypeError 错误主要发生在变量不是预期类型,或者访问不存在的方法时发生,实际开发过程中会有很多原因导致这种错误,尤其是在使用类型特定的操作而变量类型不对时发生,比如这个:

let str = "hello";
str.forEach((element) => {
  console.log(element);
});

将抛出以下错误,因为 forEach 方法只能在数组类型对象上使用,不能在字符串上使用,因为导致抛出 TypeError 错误

错误屏幕截图 (opens new window)

参考TypeError - JavaScript | MDN (opens new window)

# RangeError

RangeError 错误会在数值越界时抛出,例如这个:

let arr = new Array(-20);

将抛出以下错误,因为定义数组时设置了并不支持的长度。

错误屏幕截图 (opens new window)

参考RangeError - JavaScript | MDN (opens new window)

# 错误类型参考

如果您需要详细了解更多 JavaScript 错误类型,请阅读MDN Javascript 错误参考 (opens new window)

# 错误处理机制

错误处理在编程中的重要性毋庸置疑,但是在应用程序的浏览器端进展缓慢,一个良好的错误处理策略可以让用户知道到底发生了什么,提高系统开发效率。

ECMA-262 第三版新增了 try-catch 语句,作为 JavaScript 处理异常的一种方式,阅读以下文档学习错误处理机制。

# 任务

现在,请你开发一个乐透球号码生成系统,按照如下要求进行错误处理。

下载letto.zip (opens new window),保存到本地,您将得到一个 index.html,script.js,style.css 三个文件。

系统介绍

乐透球生成器,分为三个部分,左边显示历史乐透球号码列表,右边显示生成的乐透球号,下面是乐透球的数值范围和个数限制工具栏。 根据您输入的数值范围,以及个数,生成符合要求的乐透球,点击生成按钮,会根据要求生成在数值范围内,不重复的乐透球号码

测试用例

  • 输入最小数:1,最大数:20,个数:10。会生成 1-20 范围内的 10 个号码不重复的乐透球。
  • 输入最小数:1,最大数:49,个数:7。会生成 1-49 范围内的 7 个号码不重复的乐透球。

如果您按照上面要求进行输入,系统会正常运行,但是当你输入不符合要求的数值,系统的运行就会报错

  • 不合法乐透球个数错误:

    • 输入最小数:1,最大数:20,个数:-2。乐透球个数不可能为负数,这显然不符合要求,系统会报一个 RangeError 类型的错误,得到错误截图 (opens new window)
    • 输入最小数:1,最大数:5,个数:10。会生成 1-5 范围内的 10 个号码不重复的乐透球,这显然也是不符合逻辑的,这时页面会卡死,陷入死循环
  • 不合法数值范围错误:

    • 输入最小数:1,最大数:1000,个数:9,会生成 1-1000 范围内的 9 个号码不重复的乐透球,然而乐透球数值范围应该为 1-49,这时系统会报一个 TypeError 类型错误,得到错误截图 (opens new window)
    • 输入最小数:100,最大数:-100,个数:9 最大数小于了最小数,显示不符合逻辑,同样,系统会报一个 TypeError 类型错误,得到错误截图 (opens new window)

自定义错误类型

请您根据不同情况抛出不同的错误,以提高程序的维护性,让错误更加清晰明了

  • 不合法乐透球个数错误:

    • 当乐透球个数输入为负数时,比如输入-1,请在这种情况抛出一个 invalidBallNumError 继承于 Error 类型,错误信息为 乐透球个数为负值,不合法!
    • 当乐透球个数大于数值范围时,页面陷入死循环。请在这种情况抛出一个 invalidBallNumError 继承于 Error 类型,错误信息为 乐透球个数超过数值范围,不合法!
  • 不合法数值范围错误:当输入的乐透球数值范围大于 1-49 请你在这种情况抛出一个 invalidRangeNumError 继承于 Error 类型,错误信息为 不合法数值范围错误:数值范围不符合1-49!

  • 数值上限小于下限错误:请您在这种情况抛出一个依旧 invalidRangeNumError (继承于 Error 类型),错误信息为 不合法数值范围错误:最小数大于最大数,

针对不同类型错误进行错误捕获和处理

使用断点定位到点击事件,捕捉错误:

  • 判断错误类型如果是 invalidBallNumError 错误,就将焦点放置个数输入框上,并且将错误信息提示给用户,要求用户重新输入
  • 判断错误类型如果是 invalidRangeNumError 错误,就将焦点放置最小数输入框上,并且将错误信息提示给用户,要求用户重新输入数值范围
  • 判断错误类型如果是其他类型,就重新抛出错误。

# 自测问题

本节包含一些问题,供您检查您对本课程的理解。如果您自己无法回答以下问题,请查看以上材料以找到答案。

  • 列举出 TypeError 错误类型出现的三个原因
  • 错误和警告之间的主要区别是什么?
  • 可用于解决错误的一种方法是什么?
  • 下面这段代码会输出什么?
function test() {
  try {
    return 2;
  } catch (error) {
    return 1;
  } finally {
    return 0;
    console.log(a);
  }
}
console.log(test());
  • 思考 try/catach 使用场景