Skip to content
电脑工程师入门

电脑工程师入门

create tomorrow, create happiness

  • 实用软件教程
    • Excel
    • WordPress
    • Powerpoint
    • PowerApps
    • PowerAutomateDesk
  • 计算机语言入门
    • PHP
    • Bootstrap
    • JavaScript
    • Python
    • HTML
    • WordPress
  • 咨询
  • Home
  • JavaScript
  • 第十七章 异常处理
  • HOME
  • JavaScript
  • 第十七章 异常处理

第十七章 异常处理

JavaScript

当程序执行过程中发生意外错误时,会抛出一个异常来确定应该针对该错误采取什么操作,但是如果异常本来可以提前抛出,您可以通过编程方式描述如何处理它。在这里,我将解释如何描述如何在 JavaScript 中处理异常。

目录

17-1 使用 try…catch 语句的异常处理
17-2 使用 try…catch…finally 语句进行异常处理
17-3 如果在 try 块中调用的函数中发生异常
17-4 捕获异常时根据异常类型单独处理
17-5 使用 throw 语句抛出异常

17-1 使用 try…catch 语句的异常处理

如果程序出现错误抛出异常,如果没有设置异常处理,程序会在此时被强制终止。使用 try…catch 语句来处理异常而不在抛出异常时中止。本节说明如何使用 try…catch 语句描述异常处理。

抛出异常时的行为

首先,让我们检查在不包含任何异常处理的程序中抛出异常时的行为。看看下面的示例。

function sum(a, b){
  let sum = a + b;
  return sum;
}

console.log('Start');

let result = sum(10, 8);
console.log(result);

console.log('End');

>> Start
>> 18
>> End

下面是一个使用简单函数的示例,该函数接受两个参数并返回它们的和。如果在调用函数时为两者指定数值,则不会发生错误。

让我们稍微改变一下示例,将调用函数时的参数之一更改为长整型值。

function sum(a, b){
  let sum = a + b;
  return sum;
}

console.log('Start');

let result = sum(10, 8n);
console.log(result);

console.log('End');

>> Start
>> TypeError: Cannot mix BigInt and other types, use explicit conversions

这次在程序中间出现了TypeError。这是因为不能对数字和长整数值进行操作。程序运行过程中出现错误时抛出异常。如果没有编写代码来捕捉抛出的异常并进行适当的处​​理,程序将过早终止,如本例所示。

try…catch 语句用于捕获异常并采取适当的操作。在此之后,我将解释如何使用它。

如何使用 try…catch 语句

try…catch 语句允许您捕获抛出的异常并描述要做什么。格式如下。

try{
   编写可以引发异常的语句
  ・・・
} catch(e) {
  捕获到异常时怎么办
  ・・・
}

在 try 之后的块中编写可以引发异常的语句。仅捕获在此块内完成的处理抛出的异常。当发生错误并抛出异常时,依次执行catch之后的block中的处理。

catch后括号中写的变量e(变量名任意)存放异常抛出时设置的值。通常它是一个 Error 对象,但是如果你自己抛出异常,你可以指定任何值,所以它并不总是一个 Error 对象。

让我们修改前面的示例并使用 try…catch 语句添加异常处理。

function sum(a, b){
  let sum;
  try{
    sum = a + b;
  } catch(e) {
    console.error(e);
    return null;
  }

  return sum;
}

console.log('Start');

console.log(sum(10, 8));
console.log(sum(10, 8n));

console.log('End');

>> Start
>> 18
>> TypeError: Cannot mix BigInt and other types, use explicit conversions
>> null
>> End

在 try 块中编写一条语句,将变量添加到函数中。如果此语句抛出异常,现在您可以捕获异常。并且它描述了在catch块中捕获到异常时将执行的处理。这一次,将Error对象的内容输出到控制台后,将null返回给函数的调用者。

在本示例中,第一次调用函数时没有发生错误,因此进行了处理,使得没有 tyr…catch 语句。并且第二次调用该函数时,出现错误,也抛出异常,没有强制终止with,是运行到最后。

17-2 使用 try…catch…finally 语句进行异常处理

通过在描述异常处理时使用 try…catch…finally 语句,可以使用 finally 块来描述无论是否捕获到异常都将执行的操作。本节说明如何使用 try…catch…finally 语句描述异常处理。

使用 try…catch…finally 语句

try…catch…finally 语句允许您编写始终最后执行的操作,无论 try 块中是否抛出异常。格式如下。

try{
  编写可以引发异常的语句
  ・・・
} catch(e) {
  捕获到异常时怎么办
  ・・・
} finally {
  最后行动
  ・・・
}

finally 之后的块总是在 try 块完成处理后执行,或者如果抛出异常则在 catch 块之后执行。在 try 或 catch 块内执行任何 retnrn、break 等语句之前执行,即使处理从 try…catch…finally 语句移开。将是

如果在try块中进行文件处理或数据库处理时,不管是否抛出异常,最后都想关闭文件连接或断开数据库连接,好像经常用到。

这是一个检查操作的简单示例。

function sum(a, b){
  let sum;
  try{
    sum = a + b;
  } catch(e) {
    console.error(e);
    return null;
  } finally {
    console.log('Finally!');
  }

  return sum;
}

console.log('Start');

console.log(sum(10, 8));
console.log(sum(10, 8n));

console.log('End');

>> Start
>> Finally!
>> 18
>> TypeError: Cannot mix BigInt and other types, use explicit conversions
>> Finally!
>> null
>> End

能抛出异常的语句写在try块中,捕获到异常时的处理写在catch块中。而 finally 块描述了无论是否捕获到异常都将在最后执行的处理。

在这个例子中,第一次调用该函数时没有发生任何错误,所以 tyr…catch…finally 语句就像什么都不存在一样处理。即使在这种情况下,finally 块内的处理也会执行。并且第二次调用该函数时,出现错误,也抛出异常,没有强制终止with,是运行到最后。而且即使捕获到异常,finally块中的处理也会执行。

没有catch的try…finally语句的格式是没有问题的。

try{
  编写可以引发异常的语句
  ・・・
} finally {
   最后行动
  ・・・
}

但是,如果没有catch,就无法捕捉到异常,所以如果抛出异常,程序就会被强行终止。

17-3 如果在 try 块中调用的函数中发生异常

使用 try…catch 语句的异常处理捕获异常并在 try 块中编写的语句抛出异常时执行处理。即使异常发生在 . 但是,使用回调函数时要小心。本节说明如何处理在 try 块中调用的函数中发生的异常。

如果在 try 块中调用的函数中发生异常

try…catch语句的格式如下,可能导致异常的语句必须写在try之后的块中。

try{
  编写可以引发异常的语句
  ・・・
} catch(e) {
 捕获到异常时怎么办
  ・・・
}

那么如果 try 块在 try…catch 语句之外调用一个函数并且在该函数内部抛出异常会发生什么?

function func(){
  // 这里出现异常
}

try{
  func();
} catch(e) {
   捕获到异常时怎么办
  ・・・
}

即使在这种情况下,也与在 try 块中抛出异常时一样捕获异常,并执行 catch 之后的块中的处理。

看看下面的示例。

function sum(a, b){
  let sum;
  sum = a + b;

  return sum;
}

console.log('Start');

try{
  console.log(sum(10, 8));
  console.log(sum(10, 8n));
} catch(e) {
  console.error(e);
}

console.log('End');

>> Start
>> 18
>> TypeError: Cannot mix BigInt and other types, use explicit conversions
>> End

在这个示例中,调用函数的语句写在try块中,而不是将可能产生异常的函数写在try块中。被调用的函数没有写在 try 块中,但即使在这种情况下,函数抛出的异常也可以被函数的调用者捕获和处理。

请看另一个例子。

function sumB(a, b){
  let sum;
  sum = a + b;

  return sum;
}

function sumA(a, b){
  return sumB(a, b);
}

console.log('Start');

try{
  console.log(sumA(10, 8));
  console.log(sumA(10, 8n));
} catch(e) {
  console.error(e);
}

console.log('End');

>> Start
>> 18
>> TypeError: Cannot mix BigInt and other types, use explicit conversions
>> End

我们稍微修改了前面的示例并在两者之间放置了另一个函数。即使在这种情况下,最终调用的函数中抛出的异常也会追溯到调用者,如果在某个时候可以使用 try…catch 语句捕获异常,则会处理该异常。可以做。

异步处理回调函数出现异常时

我之前解释过,调用函数中发生的异常可以被函数的调用者捕获,但有一些注意事项。重点是无法捕获执行异步处理的回调函数中发生的异常。

看看下面的示例。这是一个简单的程序,在指定时间过去后使用 setTimeout 函数调用指定为参数的回调函数。

console.log('Start');

setTimeout(function sum(a, b){
  let sum = a + b;
  console.log(sum);
},1000, 10, 8);

console.log('End');

>> Start
>> End

>> 18

由于 setTimeout 函数的第二个参数指定了 1000 毫秒(1 秒),因此从 setTimeout 方法执行 1 秒后调用第一个参数指定的回调函数,并将运行结果显示在控制台输出.

由于这个回调函数可能会出现异常,所以将setTimeout函数的部分写在try块中,并将传递给回调函数的参数值改为几天和一个长整型。增加。

console.log('Start');

try{
  setTimeout(function sum(a, b){
    let sum = a + b;
    console.log(sum);
  },1000, 10, 8n);
} catch(e) {
  console.error('异常被捕获);
}

console.log('End');

>> Start
>> End
>> Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

我在运行这个示例时,回调函数中发生的异常无法被try…catch语句捕获,错误输出到控制台,程序被强行终止。这是因为回调函数在 try 块内部,但您是从 try 块外部调用回调函数。

请注意,在像这样的异步处理中使用回调函数时,无法捕获回调函数内发生的异常。

17-4 捕获异常时根据异常类型单独处理

有几种类型的错误会导致抛出异常。如果在使用try…catch 语句的异常处理中可能会出现多种类型的异常,则可以通过为抛出的每种类型的异常编写多个catch 来分离要执行的处理。在这里,我将说明在使用try…catch语句捕获异常时,如何根据异常类型来划分处理。

引发异常的错误类型

例外が発生するエラーの種類として次の 8 種類がグローバルオブジェクトとして定義されています。

Error           一般错误
EvalError       与eval函数相关的错误
InternalError   JavaScript内部错误
RangeError      数字超出有效范围时的错误
ReferenceError  无效引用时的错误
SyntaxError     JavaScript语法错误
TypeError       变量或参数类型错误时的错误
URIError        encodeURI或decodeURI 错误

不过SyntaxError不是运行时的错误,而是执行前的错误,所以除非你显式创建一个SyntaxError对象并抛出,否则不会因为语法错误而在运行时抛出异常。我认为。

例如,Number 对象的 toString 方法只接受 2 到 36 范围内的值作为参数,但如果指定了超出该范围的值,则会发生 RangeError。

let num = 10;
console.log(num.toString(100));
>> RangeError: toString() radix argument must be between 2 and 36

此外,即使在同一过程中也可能出现多种类型的错误。Number 对象的 toFixed 方法只接受 0 到 100 范围内的值作为参数,但如果值超出该范围,则会引发 RangeError。此外,在非数字值上调用此方法将引发 TypeError。此外,在不带括号的整数数字文字上调用此方法将引发 SyntaxError。

let num = 3.14;
console.log(num.toFixed(1000));
>> RangeError: toFixed() digits argument must be between 0 and 100

let str = '3.14';
console.log(str.toFixed());
>> TypeError: str.toFixed is not a function

console.log(24.toFixed());
>> SyntaxError: Invalid or unexpected token

try…catch 语句可以捕获抛出的任何类型的异常,但它也可以处理捕获的不同类型的异常。

根据异常类型分离要执行的处理

如果想不管异常的类型都做同样的处理,写成如下。

function returnFixed(num, digits){
  try{
    return num.toFixed(digits)
  } catch(e) {
    console.error(e);
    return null;
  }
}

console.log('Start');

console.log(returnFixed(3.87654, 3));
console.log(returnFixed(3.87654, 1000));
console.log(returnFixed('3.87654', 1000));

console.log('End');

>> Start
>> 3.877
>> RangeError: toFixed() digits argument must be between 0 and 100
>> null
>> TypeError: num.toFixed is not a function
>> null
>> End

在此示例中,调用了带有 try…catch 语句的外部函数三次。第一次返回成功结果,但是第二次和第三次都抛出异常。第二次和第三次发生的异常类型不同,但在同一个catch块中进行了相同的处理。

如果要对发生的每种类型的异常分别执行处理,请在 catch 之后检查括号中描述的变量 e 中存储的值并执行条件分支。

try{
  例外が発生する可能性がある文を記述
  ・・・
} catch(e) {
  if (e instanceof RangeError){
    // RangeError 如果发生 RangeError怎么办
    ・・・
  } else if (e instanceof TypeError){
    // TypeError 如果引发 TypeError怎么办
    ・・・
  } else {
    // 发生上述以外的异常时执行的处理
    ・・・
  }
}

catch 之后的变量包含抛出异常时设置的值。您可以通过使用 instanceof 运算符将此值与 RangeError 或 TypeError 对象进行比较来确定异常的类型。

现在,让我们改变之前的示例,以便对每种类型的异常执行不同的处理。

function returnFixed(num, digits){
  try{
    return num.toFixed(digits)
  } catch(e) {
    if (e instanceof RangeError){
      console.error('RangeError');
      return null;
    } else if (e instanceof TypeError){
      console.error('TypeError');
      return null;
    } else {
      console.error(e);
      return null;
    }
  }
}

console.log('Start');

console.log(returnFixed(3.87654, 3));
console.log(returnFixed(3.87654, 1000));
console.log(returnFixed('3.87654', 1000));

console.log('End');

>> Start
>> 3.877
>> RangeError
>> null
>> TypeError
>> null
>> End

更改为根据发生的异常类型执行不同的处理。

17-5 使用 throw 语句抛出异常

当程序执行过程中出现错误时就会抛出异常,但你可以随时使用throw语句抛出异常。本节介绍如何使用 throw 语句抛出异常。

throw如何使用抛出语句

可以使用 throw 语句抛出异常。格式如下。

throw 异常值

异常值通常是一个 Error 对象,但也可以是任何值,例如数字或字符串。当使用 try…catch 语句捕获异常时,此处指定的异常值将存储在 catch 括号内写入的变量中。

看看下面的示例。

function checkResult(point){
  try{
    if (point < 50){
      throw '失败';
    }

    console.log('分数' + point);
    console.log('通过');
  } catch(e) {
    console.error(e);
  }
}

console.log('Start');

console.log(checkResult(82));
console.log(checkResult(40));

console.log('End');

>> Start
>> 得分82
>> 通过
>> 失败
>> End

在此示例中,我们检查函数中作为参数传递的值,如果小于 50 则抛出异常。这次我们指定一个字符串作为异常值。抛出的异常由 try…catch 语句捕获,并执行 catch 块内描述的处理。

标签:JavaScript

文章导航

❮ Previous Post: 第十六章 深度函数讲解
Next Post: 第十八章 正则表达式 ❯

关联内容

JavaScript
第二章将JavaScript写到HTML编码中
JavaScript
第一章 在浏览器中启用 JavaScript
JavaScript
第三章 JavaScript 基础知识
JavaScript
第四章 JavaScript的数值
JavaScript
第五章 長整数
JavaScript
第六章 字符串的基础

实用软件教程

  • Powerpoint
  • Excel
  • PowerAutomateDesk
  • Wordpress
  • Powerapps

编程语言入门

  • JavaScript
  • HTML
  • PHP
  • Python
  • Bootstrap

Copy right by flashyonder.com