JavaScript异常处理详解
前言
本文将带你了解 JavaScript 中常见的错误类型,处理同步和异步 JavaScript代码中错误和异常的方式,以及错误处理最佳实践!
1. 错误概述
JavaScript 中的错误是一个对象,在发生错误时会抛出该对象以停止程序。在 JavaScript 中,可以通过构造函数来创建一个新的通用错误:
const err = new Error("Error");
也可以省略new关键字
const err = Error("Error");
Error 对象有三个属性:
- message:带有错误消息的字符串;
- name: 错误的类型;
- stack:函数执行的堆栈跟踪。
下面的代码示例展示了TypeError的name、message、stack
let str = null;
try{
str.forEach((item,index)=>{
console.log(item)
})
}catch(e){
console.log(e);
console.log("name:",e.name);
console.log("message:",e.message);
console.log("stack:",e.stack)
}
// 输出结果:
// name: TypeError
// message: Cannot read properties of null (reading 'forEach')
// stack: TypeError: Cannot read properties of null (reading 'forEach')
// at file:///C:/Users/Administrator/Desktop/ErrorTest.html:14:17
2. 错误的捕获
2.1 基本的try…catch语句
ES3开始引入了 try-catch 语句,是 JavaScript 中处理异常的标准方式。
语法:
try{
?
//可能发生异常的代码?}catch(error){
?
//发生错误执行的代码?}
看下面的代码:
<script>
try{
console.log(b);
console.log("我不会输出的,不要找了")
}catch(error){
console.log("发生错误了")
}
console.log("我try catch后面的代码")
</script>
说明:
- 把有可能出的问题的代码放在 try 语句中。try语句中可以理论上可以写任何的代码,只要有一行代码出现问题,整个程序的执行流程就会立即调到catch语句中执行。
- 一旦try中有一行代码发生异常,则这行出错代码的后面的try中的其他语句都不会再执行。比如上面代码中的
console.log(b);
这行代码会出错,则立即去执行catch中的代码。所以console.log("我不会输出的,不要找了")
这行代码则不会再执行 - 在执行catch中的代码之前,js引擎会首先根据错误类型自动创建一个错误,并通过catch后面的参数传递到catch中。不同的浏览器创建的error对象不一样,但是同创他们都包含一个message属性,值是这个错误的一些信息。
- catch中的代码执行完毕之后,会继续执行后面的代码,程序不会停止下来。
2.2 finally语句
在 try…catch 中,try 中一旦出现错误则其他语句不能执行,如果不出现错误则 catch 中的语句不会执行。
Javascript 参考其他编程语言,也提供了一种 finally 语句:不管 try 中的语句有没有错误,在最后都会执行 finally 中的语句。
即:try 中语句不发生错误执行完毕后会执行 finally 中的语句,try 中的语句发生错误,则执行 catch中的语句,catch 中的语句执行完毕后也会执行 finally 中的语句。
语法:
try{
}catch(error){
}finally{
}
<script>
try{
console.log(b);
console.log("我不会输出的,不要找了")
}catch(error){
console.log("发生错误了")
}finally {
console.log("不管发生不发生错误,我都会执行")
}
console.log("我try catch后面的代码")
</script>
所以在 finally 中我们可以放置我们必须要执行的代码。
注意:
- 在js中,如果添加了 finally 语句,则 catch 语句可以省略。所以下面的代码也是正确的。
- 如果没有 catch 语句,则一旦发生错误就无法捕获这个错误,所以在执行完 finally 中的语句后,程序就会立即停止了。
- 所以,在实际使用中,最好一直带着 catch 语句。
2.3 合理使用try…catch
?当 try-catch 语句中发生错误时,浏览器会认为错误已经被处理了,浏览器就不再报告错误了。这也是最简单的一种情况。
使用 try-catch 最适合处理那些我们无法控制的错误。假设你在使用一个大型 JavaScript 库中的 函数,该函数可能会有意无意地抛出一些错误。由于我们不能修改这个库的源代码,所以大可将对该函 数的调用放在 try-catch 语句当中,一有什么错误发生,也好可以恰当地处理它们。
在明明知道自己的代码会发生错误时,再使用 try-catch 语句就不太合适了。例如,如果 传给函数的参数是字符串而非数值,就会造成函数出错,那么就应该先检查参数的类型,然后再决定 如何去做。在这种情况下,不应用使用 try-catch 语句。因为try…catch语句比较是比较好资源的事情。
?
3. 错误类型
3.1 JavaScript提供的错误类型
JavaScript 中有一系列预定义的错误类型。只要使用者没有明确处理应用程序中的错误,它们就会由 JavaScript 运行时自动选择和定义。JavaScript中的错误类型包括:
EvalError | |
InternalError | InternalError 表示内部错误。在 JavaScript 运行时引擎发生异常时使用。它表示代码可能存在问题也可能不存在问题。 |
RangeError | RangeError 表示范围错误。当变量设置的值超出其合法值范围时,将抛出 RangeError。它通常发生在将值作为参数传递给函数时,并且给定值不在函数参数的范围内。当使用记录不完整的第三方库时,有时修复起来会很棘手,因为需要知道参数的可能值范围才能传递正确的值。 |
ReferenceError | ReferenceError 表示引用错误。当代码中的变量引用有问题时,会发生 ReferenceError。可能忘记在使用变量之前为其定义一个值,或者可能试图在代码中使用一个不可访问的变量。在任何情况下,通过堆栈跟踪都可以提供充足的信息来查找和修复有问题的变量引用。 |
SyntaxError | SyntaxError 表示语法错误。这些错误是最容易修复的错误之一,因为它们表明代码语法中存在错误。由于 JavaScript 是一种解释而非编译的脚本语言,因此当应用程序执行包含错误的脚本时会抛出这些错误。在编译语言的情况下,此类错误在编译期间被识别。因此,在修复这些问题之前,不会创建应用程序二进制文件。 |
TypeError | TypeError 是 JavaScript 应用程序中最常见的错误之一,当某些值不是特定的预期类型时,就会产生此错误。 |
URIError | URIError 表示 URI错误。当 URI 的编码和解码出现问题时,会抛出 URIError。JavaScript 中的 URI 操作函数包括:decodeURI、decodeURIComponent 等。如果使用了错误的参数(无效字符),就会抛出 URIError。 |
这些错误类型都是实际的构造函数,旨在返回一个新的错误对象。最常见的就是 TypeError。大多数时候,大部分错误将直接来自 JavaScript 引擎,例如 InternalError 或 SyntaxError。JavaScript 提供了 instanceof 运算符可以用于区分异常类型:?
try {
If (typeof x !== ‘number’) {
throw new TypeError(‘x 应是数字’);
} else if (x <= 0) {
throw new RangeError('x 应大于 0');
} else {
// ...
}
} catch (err) {
if (err instanceof TypeError) {
// 处理 TypeError 错误
} else if (err instanceof RangeError) {
// 处理 RangeError 错误
} else {
// 处理其他类型错误
}
}
?3.2?自定义错误类型
虽然 JavaScript 提供了足够的错误类型类列表来涵盖大多数情况,但如果这些错误类型不能满足要求,还可以创建新的错误类型。这种灵活性的基础在于 JavaScript 允许使用 throw 命令抛出任何内容。可以通过扩展 Error 类以创建自定义错误类:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
自定义类型的使用
throw ValidationError("未找到该属性: name")
?可以使用 instanceof 关键字识别它:
try {
validateForm() // 抛出 ValidationError 的代码
} catch (e) {
if (e instanceof ValidationError) {
}
else {
}
}
4. throw主动抛出异常
4.1 抛出js内置错误类型的对象
? 在大部分的代码执行过程中,都是出现错误的时候,由浏览器(javascript引擎)抛出异常,然后程序或者停止执行,或被try…catch 捕获。
? 然而有时候我们在检测到一些不合理的情况发生的时候也可以主动抛出错误。
? 使用 throw 关键字抛出来主动抛出异常。
<script>
throw new Error("你好坏");
console.log("执行不到这里的")
</script>
注意:
- thow后面就是我们要抛出的异常对象。在以前的时候都是出现错误的时候浏览器抛出异常对象,只是现在是我们自己主动抛出的异常对象。
- 只要有异常对象抛出,不管是浏览器抛出的,还是代码主动抛出,都会让程序停止执行。如果想让程序继续执行,则有也可以用try…catch来捕获。
- 每一个错误类型都可以传入一个参数,表示实际的错误信息。
- 我们可以在适当的时候抛出任何我们想抛出的异常类型。
throw new SyntaxError("语法错误...");
看下面的代码:
<script>
/*该函数接收一个数字,返回他的平方。*/
function foo(num) {
if(typeof num == "number"){
return num * num;
}else{
throw new TypeError("类型错误,你应该传入一个数字...")
}
}
console.log(foo(33))
console.log(foo("abc"))
</script>
4.2 抛出自定义类型的错误对象
? 我们不仅仅可以抛出js内置的错误类型的对象,也可以自定义错误类型,然后抛出自定义错误类型的对象。
? 如果要自定义错误类型,只需要继承任何一个自定义错误类型都可以。一般直接继承Error即可。
<script>
function MyError(message) {
this.message = "注意:这是自定义的错误"
this.name = "自定义错误";
}
MyError.prototype = new Error();
try {
throw new MyError("注意:这是自定义错误类型")
}catch (error){
console.log(error.message)
}
</script>
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!