Javascript中throw、Error、try catch使用

401 阅读3分钟

throw

看下列代码:

function add(num1, num2) {
    if (typeof num1 !== "number" || typeof num2 !== "number") {
      return;
    }

    return num1 + num2;
  }

add(10,20)
add(10,"111")

在上面代码中,我们希望add函数接收的参数为数字类型,如果不是数字类型那么就不继续执行函数,所以采用了return来终止函数的执行。但是,在js中,如果直接return其实是有返回值的,返回值是undefined的,而且我们希望告诉函数使用者,为什么返回了个undefined,想传递一些错误信息给使用者,比如错误位置、调用栈信息等,单纯使用return来返回这些信息是比较难做到的。所以有了throw语句,通过throw来抛出一个异常。

function add(num1, num2) {
    if (typeof num1 !== "number" || typeof num2 !== "number") {
      throw "params type error";
    }

    return num1 + num2;
  }

add(10,20)
add(10,"111")

这样,我们浏览器就会抛出一个错误:

image.png

throw后面可以跟基本数据类型,如string、number等,也可以跟一个对象,而对象可以让我们记录更多的错误信息。

Error

Error是一个构造函数,可以帮我们生成一个错误对象。我们可以配合throw这样使用:

function foo(){
    throw new Error("error 123")
}
foo()

image.png

这样就会帮我们抛出一个错误对象。这个错误对象包含三个属性:

  1. messsage:创建Error对象时传入的message;
  2. name:Error的名称,通常和类的名称一致;
  3. stack:整个Error的错误信息,包括函数的调用栈,当我们直接打印Error对象时,打印的就是stack

Error作为一个类,还有自己的子类:

  1. RangeError:下标值越界时使用的错误类型;
  2. SyntaxError:解析语法错误时使用的错误类型;
  3. TypeError:出现类型错误时,使用的错误类型;

try catch 异常处理

在上面我们使用throw的时候会发现,一旦执行到throw抛出异常后,我们后面所有的代码都将不会被执行,但在实际应用中,我们是不希望这样的,就算抛出异常,我们依然希望别的代码继续执行。这时我们就需要用try catch来捕获这个错误并进行处理了:

  function foo() {
    throw new Error("error 123");
  }
  function bar() {
    try {
      foo();
    } catch (err) {
      console.log("处理错误");
    } 
  }
  bar();
  console.log("bar函数后的代码");

执行上面代码,最后打印:

image.png

我们可以发现,即使bar内的foo函数抛出异常后代码也照常执行。

这里注意一下,对于抛出错误,在js中是一直往上一层进行抛出的。比如上面代码,当foo函数throw过后抛出了异常,如果在foo内没有捕获,那么就会将这个错误抛出到调用foo函数的bar函数,如果bar函数我们没有捕获这个错误进行处理那么就会继续往上抛,直到最顶层都还没有对这个错误进行捕获处理,那么这时就会抛出错误并停止程序运行。

在最后还有一个finally方法,finally内的代码块是无论是否抛出异常都会执行,一般在这里做一些代码的收尾工作:

  function foo() {
    throw new Error("error 123");
  }
  function bar() {
    try {
      foo();
    } catch (err) {
      console.log("处理错误");
    } finally{
        console.log("finally")
    }
  }
  bar();

注意:如果try和finally中都有返回值,那么会使用finally当中的返回值

  function foo() {
    return 11;
  }
  function bar() {
    try {
      return foo();
    } catch (err) {
      console.log("处理错误:", err);
    } finally {
      return 20;
    }
  }
  console.log(bar());//20

在es10中,catch可以不用跟一个参数进行使用,即可以这样:

try{
    ...
}catch{
    ...
}