当前位置: 首页 > Web前端 > HTML

错误检测(一)------try-catch语句来自《高程3》

时间:2023-04-02 13:24:43 HTML

0前言现在看完了《高程3》的错误检测部分,现在先挖个坑,写三个关于错误检测的总结:firebugdetectionerror和输出信息;try-catch错误捕获;常见的错误类型。本文逻辑如下:首先引入try-catch语句进行错误捕获;然后介绍常见的错误类型,结合firebug进行讲解;其次介绍使用try-catch语句结合错误类型来捕获错误;但是如果capture的错误是用浏览器的语言表达的,还是很难发现错误,所以推荐使用throw抛出开发者定义的错误,这样错误的位置和原因就会更容易找到;最后对错误抛出和错误捕获进行总结讨论。1try-catch简介一个好的错误处理机制可以让用户和开发者及时得到提醒,知道发生了什么,从而不会惊慌失措。ECMA-262第3版引入了try-catch语句作为JavaScript中处理异常的标准方法。基本语法如下,try{//可能导致错误的代码}catch(error){//错误发生时怎么办}我们应该把所有可能抛出错误的代码放在try语句块中,并将错误处理代码放在catch块中。如果try块中的任何代码发生错误,则立即退出代码执行过程,然后执行catch块。此时,catch块将接收到一个包含错误信息的对象。即使您不想使用此错误对象,也要指定一个参数名称。该对象中包含的实际信息因浏览器而异,但通常都有一个保存错误消息的消息属性。message属性是唯一保证所有浏览器都支持的属性。此外,IE、Firefox、Safari、Chrome和Opera都在错误对象中添加了其他相关信息。在跨浏览器编程时,最好只使用message属性。一个测试例子:只要代码中包含finally子句,无论try或catch语句块中包含什么代码——即使是return语句,也不会阻止finally子句的执行。如下例所示:functiontestFinally(){try{return2;}赶上(错误){返回1;}最后{返回0;}}functiontestWithoutFinally(){try{return2;}赶上(错误){返回1;}}console.log(testFinally());//输出0console.log(testWithoutFinally());//输出2如果提供了finally子句,则catch子句变为可选(catch或finally有一个即可)。IE7及更早版本有一个bug:除非有catch子句,否则finally里面的代码永远不会执行。IE8修复了这个错误。如果你仍然想考虑早期版本的IE,那么你必须提供一个catch子句,即使里面什么也没写。另一个测试例子:varexample=function(){try{window.someNonexistentFunction();}catch(error){console.log(error.name);控制台日志(错误信息);返回1;}finally{console.log('一切都结束了');}};例子();测试结果:try/catch/finally中的语句依次执行。问题是为什么最后执行catch中的return语句?给自己留个问题。2错误类型每个错误都有对应的错误类型,当错误发生时,会抛出对应类型的错误对象(errorobject)。ECMA-262定义了以下七种错误类型:1)错误是其他错误类型继承的基本类型。因此,所有错误类型共享同一组属性(错误对象中的方法都是默认对象方法)。2)使用eval()函数时出现异常会抛出EvalError类型的错误,但抛出的错误不一定是EvalError类型。如果未将eval()作为函数调用,Firefox4+和IE8会抛出TypeError。3)当值超出对应的范围时,会触发RangeError类型的错误。例如,在定义数组时,如果指定了数组不支持的项数(例如-20或Number.MAX_VALUE),则会触发此错误。4)在找不到对象的情况下,会出现ReferenceError(在这种情况下,会直接导致众所周知的“objectexpected”浏览器错误)。通常,当访问不存在的变量时会发生此错误。5)至于SyntaxError,当我们将一个语法错误的JavaScript字符串传递给eval()函数时,就会出现这种类型的错误。如果语法错误的代码出现在eval()函数之外,则不太可能使用SyntaxError,因为此时的语法错误会导致JavaScript代码立即停止执行。6)TypeError类型在JavaScript中经常使用。当变量中存储了一个不期望的类型,或者访问了一个不存在的方法时,就会产生这个错误。报错的原因有很多种,归根结底是在进行特定类型的操作时,变量的类型不符合要求。最常见的类型错误发生在没有事先检查传递给函数的参数时,传入的类型与预期类型不匹配。7)当使用encodeURI()或decodeURI()时,URI格式不正确,会导致URIError错误。这种错误也很少见,因为上面提到的两个函数的容错度都很高。上面在FF中的测试过程如下:3使用try-catch语句捕获错误要知道错误的类型,可以在try-catch语句的catch语句中使用instanceof操作符,如下所示。try{someFunction();}catch(error){if(errorinstanceofTypeError){//处理类型错误}elseif(errorinstanceofReferenceError){//处理引用错误}else{//处理其他类型的错误}}在跨浏览器编程中,检查错误类型是确定如何处理错误的最简单方法;message属性中包含的错误消息因浏览器而异。使用try-catch最适合处理我们无法控制的错误。假设你正在使用大型JavaScript库中的函数,它可能有意或无意地抛出一些错误。由于我们无法修改这个库的源码,所以我们可以把这个函数的调用放在一个try-catch语句中,这样一旦出现错误,就可以进行适当的处??理。4throw抛出自定义错误还有一个throw操作符匹配try-catch语句,用于随时抛出自定义错误。抛出错误时,必须为throw运算符指定一个值。这个值是什么类型没有要求。遇到抛出运算符时,代码执行会立即停止。仅当try-catch语句捕获到抛出的值时,代码才会继续执行。通过使用自定义的内置错误类型,可以更真实地模拟浏览器错误。每种错误类型的构造函数接收一个参数,即实际的错误消息。下面是一个例子。thrownewError("发生了不好的事情。");thrownewSyntaxError("我不喜欢你的语法。");thrownewTypeError("你认为我是什么类型的变量?");thrownewRangeError(“抱歉,你只是没有范围。”);thrownewEvalError(“那不评估。”);thrownewURIError(“Uri,是你吗?”);thrownewReferenceError(“你没有不要正确引用你的参考文献。”);浏览器将处理这些代码抛出的错误,就好像它们是自己产生的一样。也就是说,浏览器会以正常的方式报告这个错误,并会在这里显示自定义的错误信息。抛出自定义错误的意义:方便快速定位和改正错误。虽然浏览器自己会报错,但是这些错误信息在浏览器中是不统一的,如果出现同类型的错误,查找源头很复杂,尤其是在几千行代码中。但是如果你知道可能的代码错误,你可以直接在代码中添加这些自定义错误。一旦出现这些错误,浏览器就会报一个自定义错误。关键是错误的位置和类型很明显。示例:必须接受数组作为参数的函数如果接受字符串作为参数,将报告错误。函数过程(值){values.sort();for(vari=0,len=values.length;i100){返回值[i];}}return-1;}vara=process("string");控制台日志(一);导致firebug:添加自定义错误后的代码:functionprocess(values){if(!(valuesinstanceofArray)){thrownewError("process():Argumentmustbeanarray.");}values.sort();for(vari=0,len=values.length;i100){返回值[i];}}返回-1;}vara=process("字符串");控制台日志(一);导致firebug:如果values参数不是数组,报错。错误消息包括函数名称和错误发生原因的清晰描述。如果此错误发生在复杂的Web应用程序中,则更容易找到问题的根源。原型链还可用于通过继承自Error来创建自定义错误类型。此时,需要为新建的错误类型指定name和message属性。一个例子://通过继承Error实现自定义错误类型,定义name和message属性functionCustomError(message){this.name="CustomError";this.message=消息;}CustomError.prototype=newError();functionprocess(values){//如果发生错误,抛出一个自定义错误类型的对象实例if(!(valuesinstanceofArray)){thrownewCustomError("process():Argumentmustbeanarray.");}values.sort();for(vari=0,len=values.length;i100){返回值[i];}}返回-1;}过程(“字符串”);firebug显示自定义类型的错误:5抛出错误与使用try-catch捕获错误关于何时抛出错误以及何时使用try-catch捕获错误是一个陈词滥调的问题。一般来说,错误往往是在应用架构的较低层抛出的,但这一层并不影响当前正在执行的代码,因此通常不会真正处理错误。如果你打算编写一个将在许多应用程序中使用的JavaScript库,或者甚至只是一个可能在应用程序内部多个地方使用的辅助函数,我强烈建议你在抛出错误时提供详细信息。然后可以在应用程序中捕获并适当处理这些错误。说到抛出错误与捕获错误,我们认为您应该只捕获您确切知道如何处理的错误。捕获错误的目的是防止浏览器默认处理它们;抛出错误的目的是提供错误发生原因的信息。