@想一想@:方法getGrade(score)可以处理0-100分之间的成绩(score),但当该方法被调用时传入的参数score是-60或者150时,咋办?
我们之前的方案是 1. return 和 2. 控制台输出。
if(score<0 || score> 100){ console.log("成绩不能小于0或大于100"); return; }
但:
所以现代语言为我们提供了一种更完善的异常(exception的直译)处理机制。
在上述例子中,score在0-100之间,就是正常;超出这个范围,就是异常:
例外;一般情况以外的人(或事物)
异常又被称之为:运行时错误,对应Java/C#等编译型语言的编译时错误。
因为它们总是在运行时才会被抛出,编译时就会被发现的错误不会是异常。
需要使用关键字:throw
throw "成绩不能小于0或大于100"; //或者 throw Error("成绩不能小于0或大于100");
演示:
理解“抛出”:
所以只能抛出异常,交由“调用者”处理。
当我们的代码写得有问题的时候,比如:
console.loog();
也会出现异常(错误)信息。
所以很多同学就会觉得:
但实际上,异常只是提示可能有bug。
有些异常是:
另外:
牢记:错误暴露得越早越好!
延伸:在工作中也一样,很多同学习惯性“埋雷”。
闷着头瞎搞……
@想一想@:最终的结果是咋样的,你应该怎么做?
发现问题,就应该:
把问题扼杀于萌芽状态。
为什么我们说强类型的编译时检查非常棒,为什么我们要单元测试TDD,为什么我们要防御式编程……都是基于这个原因。
被抛出的异常,(如果没有被处理/捕获)会直接传递给它的调用者,再由调用者传递给它的调用者,...,直到程序最顶层调用,被称之为未处理(unhandled)异常,程序崩溃
为了避免程序崩溃,我们需要try...catch来捕获异常:
try{ let grade = getGrade(-80); }catch{ // console.log("给用户提示:你的输入有错"); }
如果try块里面的代码报了异常,就会进入catch块(异常被捕获);否则,跳过catch块。
演示:
注意区分:正常的log输出和未处理异常造成error
catch中还可以再抛出异常
}catch(e){ //e里面包含了所有异常信息 console.log("给用户提示:你的输入有错"); //log throw e; //把异常信息再抛出去 }
有时候我们希望一段代码无论有无异常,都要执行(主要用于清理资源,比如关闭文件流/数据库连接等),这就需要使用finally:
//在try...catch后面接上: }finally{ console.log("总是要执行"); }
演示:
异常会带来较大的资源开销(性能损耗),所以要尽可能避免异常被抛出(注意:不是不写throw exception的代码)
一种典型的错误就是把try...catch做为分支判断条件:if有异常,就catch……
比如我们上面的代码就是不对(好)的,更好的写法应该是:
if(score>100 || score<0){ console.log("给用户提示:你的输入有错"); //log return; }
@想一想@:这里的if判断和getGrade()里的if判断,重复了么?
没有重复,这叫做“各扫门前雪”。要明白:实际开发不是你现在这样所有代码一个人写,会有分工……
多快好省!前端后端,线上线下,名师精讲
更多了解 加: