Understand try/catch/finally from shallow to deep

Get into the habit of writing together! This is the 14th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .


This article was first published in: My Zhihu

Anyone who has learned try/catch/finally should know that this is a relatively simple error handling mechanism. But for beginners, some details may be difficult to understand. This article will take you to understand try/catch/finally from simple to deep.

If you think you understand it, then please read this question first.

const whoami = () => {
  try {
    try {
      return '  ';
    } catch(_) {
      return '  ';
    } finally {
      return '  ';
    }
    throw '  ';
  } catch (_) {
    return '  ';
  }
}
whoami();函数的返回值将是什么?
复制代码

1. Why use it?

try/catch/finallyUsed to handle possible errors in the code. It is needed because when JavaScritp an error occurs in the execution, the execution of the following program is stopped, and the exception that occurs can cause the program to crash . So using try/catch/finallyto handle errors is important for future project maintenance. E.g:

const PI = 3.14;
alertt('Hello!');
console.log(PI);
// ReferenceError: alertt is not defined
复制代码

Obviously alerttmisspelled , so the following program will not be executed. So use exception try/catch/finallyhandling

const PI = 3.14;
try {
  alertt('Hello!');
} catch(err) {
  console.log(err.message);
} finally {
  console.log(PI);
}
/*
alertt is not defined
3.14
*/
复制代码

2. How to use it?

  • tryStatements define the code that is executed to test for errors. If no exception is thrown inside the try, the catch will be skipped.
  • catchThe statement defines that trywhen an error occurs in the statement, the error is caught and handled. It will only execute if an error is trythrown .
  • finallyThe statement is executed regardless of whether or not an exception precedes it. |

When used, the trystatement is required ; the parameters in catch(err) are required; catch and finallyare optional. That is, the following three forms

  • try...catch
  • try...finally
  • try...catch..finally

3. throw and Error objects

3.1 throw

We can generate an error and customize the thrown exception via the throwstatement

throw 'error!';
throw false;
复制代码

例如,以下语句限制了 input 的形式

var input = 1314;
try {
  if(input == '') throw "请您输入!";
  if(isNaN(input)) throw "请输入数字!";
  if(input <= 0) throw "请输入大于0的数!"
} catch(err) {
  alert(err);
}
复制代码

3.2 throw 与 try/catch/finally

我们把外层的 try 块叫做"outer"块,把内层的称为"inner"块。如下

// "outer块"
try {
  // "inner块"
  try {
    throw "error";
  } catch(err) {
    console.log('inner:' + err);
    throw "error";
  } 
} catch(err) {
  console.log("outer:" + err);
}
/* 输出
inner:error
finally
outer:error
*/
复制代码

最后的输出结果说明,抛出的异常只会被离它最近的 catch 捕获。而且, "inner" 层抛出的异常,"outer" 外层同样可以捕获到。

3.3 Error 对象

Errornamemessage 两个属性

try {
    adddlert("Welcome");
}
catch(err) {
  console.log(err.name);
  console.log(err.message);
}
/* 输出
ReferenceError
adddlert is not defined
*/
复制代码

3.4 throw 与 Error 对象

throw new Error("error!")
复制代码

4. return 与 try/catch/finally

我们都知道,在一个函数中,一旦 return 出现后,后面的语句就不会再执行了。那如果在 try/catch/finally 里出现 return 会怎么样呢? 无论是否出现异常,又或者前面的 try/catch 里面有 return,finally 里面的语句始终会执行

try {
  return "hello";
} finally {
  console.log("finally");
}
/*输出
finally
*/
复制代码

若 try/catch/finally 里面提前出现了 return ,则该代码块里后面的部分都不会执行

const f = () => {
  try {
    return "hello";
    console.log("try");
  } finally {
    return "hello";
    console.log("finally");
  }
}
f();
//无输出
复制代码

若把 return 写入到了函数的 finally 里面,则最终函数(整个try/catch/finally)的返回值(或者抛出的异常)将是 finally 里面返回的值,即使前面 try/catch 出现了 retrun

const func = () => {
  try {
    try {
      throw new Error("ERROR!");
    } catch(err) {
      console.log(err.message);
      throw new Error("error from inner")
    } finally {
      return "finally";
    } 
  } catch(err) {
   console.log(err.message); // 未捕获到异常,此处不输出
  }
};
func();
/* output
ERROR!
*/
复制代码

若把上面的 return "finally" 注释掉,则将会输出 error from inner。这告诫我们 不要轻易在 finally 里面写 return ,否则会覆盖前面返回的函数值甚至是抛出的错误

现在再去看看开头那道题吧~

参考链接

Guess you like

Origin juejin.im/post/7086738106283458574