JS中异常处理的理解

【转】JS中异常处理的理解

JS里的异常处理

JS的异常捕获与处理可以从它的 try-catch 语法结构说起,具体形式如下:

try{
    ...    //异常的抛出
}catch(e){
    ...    //异常的捕获与处理
}finally{
    ...    //结束处理
}

其中,try块:

try块包含的是可能产生异常的代码,在这里面直接或者在里面通过调用函数里间接抛出的异常都可以捕获到。部分浏览器还可以找到具体抛出的位置。详见e.stack

catch块:

catch块,是捕获异常,并处理异常的地方,包括条件捕获和非条件捕获。

//条件捕获与非条件捕获
try {
    throw new Err();
}catch(e instanceof ErrBob) {
    console.log(e.name + ‘ Bob‘‘);
}catch(e instanceof ErrTom) {
    console.log(e.name + ‘ Tom‘‘);
}catch(e instanceof ErrLily) {
    console.log(e.name + ‘ Lily‘‘);
}catch(e) {
    console.log(‘that‘s all‘);
}

条件捕获,如 catch(e instanceof obj) 的形式,用 instanceof 判断异常的对象类型,实现指定的异常处理方式。

非条件捕获,如 catch(e)  的形式,当异常抛出时,无论异常的类型都进行捕获并处理。

这里有两点注意,如果条件捕获和非条件捕获共用,那么非条件捕获必须放在最后,因为它是无条件的捕获类型,捕获后会忽略后面的任意 catch 块。

另外,对异常的处理必须考虑周全,在 catch 里要么处理所有的异常,要么再次抛出异常(假定外层还有异常处理),否则在调试过程中会非常困难,因为出现的异常被忽略了。

finally块:

无论是否捕获异常,都会在 try 或 catch块后立即执行。

finally块常常用以文件的关闭,标记的取消等操作,更多的时候作为一种 ”优雅的失败“ 而存在,常常代替 catch 块。

在JS的DOM对象中,还有一个 window.onerror 作为事件监听来从全局处理JS运行时的错误。由于浏览器的差异,实际上许多错误事件不能触发 window.onerror ,因此要小心使用,详见《Why window.onerror Is Not Enough》

那么如何抛出异常呢?

JS里用 throw 指定一个用户定义的异常类型,并抛出。抛出点可以在 try 或 catch 块中。

throw e;
//抛出用于自定义的异常

throw ‘error‘;
throw ‘21‘;
throw true;
throw new myError(); 

这里的异常类型包括字符串、数字、布尔值和对象,如例子中所示。为了获取有用的信息,以及有条件地捕获异常,其中只有对象类型最为常用。

JS里内置的Error对象方便我们使用,‘throw new Error();’ ,同时提供了6种错误类型便于我们捕获,包括EvalError、RangeError、ReferenceError、SyntaxError、 TypeError、URIError,详见这里

更为便利的是定制一个异常的对象,可以自定义,也可以继承Error对象,主要包括 name 和 message 属性即可,例如:

try{
    throw {  name : ‘err1‘,
             message : ‘here it is‘
           };
}catch(e){
    console.log(e.name + ‘ : ‘ + e.message);
}

JS里异常处理的有两个特点:

1、活动链域和性能

  当对异常进行捕获并进入到 catch 块中,此时的异常对象 e 将成为一个新的活动对象,并提到活动链域的最前面。如下栗子:

try{
    ...
}catch(e){
   var name = ‘jberry‘;
    alert(name + e.message);    //e 在活动链域的最前面  //handleFn(e);} 

此时 catch 块中的任何标识符(例子中的 ‘name’)都将在活动链域的第二个活动对象里访问,这样降低了访问的性能。好的方法的是调用异常处理函数,减少在catch块中对标识符的访问(例子中 ‘handleFn(e);‘)。

2、错误和异常有什么区别?

在如Java一些语言中,错误和异常有所区别,它们分属不同的类别。

通常错误是非正常的系统级的严重错误,出现后程序直接终止,这种错误是不应该、或是不可预见的,不推荐用 try-catch 来捕获处理。

异常是程序运行时不满足某些条件而出现的非严重的错误,应尽量使用 try-catch 来捕获它。

而在JS中,只定义了错误(Error),作为其内置的对象,其原型对象一般包括 name 和 message 两个属性。不同的浏览器还实现了不同的错误类型以及附加的属性和方法。

异常(Exception)只是错误的另一种说法,它们实际上一个东西,都可以用 try-catch 来处理,因此不用在意它们的处理方式。一个异常的对象,在JS里实际上就是一个拥有 name 和 message 属性的Error实例罢了。

唯一不同的是,如上面所述,JS中异常可以以字符串、数字、布尔值或对象的形式来抛出处理,而错误则通常特指Error对象及其继承的自定义子对象。

时间: 2024-10-27 07:25:15

JS中异常处理的理解的相关文章

JS中的prototype理解

JS中的phototype是JS中比较难理解的一个部分 本文基于下面几个知识点: 1 原型法设计模式 在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展.我们称B的原型为A. 2 javascript的方法可以分为三类: a 类方法 b 对象方法 c 原型方法 例子: function People(name){  this.name=name;  //对象方法  this.Introduce=functi

关于js中闭包的理解

1.以前很不理解js中闭包的概念及使用,下面来看一下 function foo() { var a = 123; var b = 456; return function () { return a; } } var fn = foo(); 上面的代码只能访问 a和b,但是不能修改,这是js中闭包的技术之一 function foo() { var a = 123; var b = 456; return { get_a: function () { return a; }, set_a: fu

谈谈我对JS中this的理解

好吧,JS中,作用域.闭包和原型都说了,今天我们就谈谈this吧,this我更倾向于把它理解成为一个特殊变量,JS解释器在创建任何活动对象时(参考前面关于作用域的博文),都会创建一个this变量,并且将它指向一个对象(可编码干预).下面以代码为例进行讲解. 处于全局作用域下的this: this;/*window*/ var a = {name: this}/*window*/ var b = [this];/*window*/ 在全局作用域下,this默认指向window对象. 处在函数中的t

js中的闭包理解

闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的理解以及js内部解释器的运作方式的描述,都是可以看出你js实际水平的.即使你没答对,也能让考官对你的水平有个评估.那么我先来说说我对js中的闭包的理解. 闭包是很多语言都具备的特性,在js中,闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等. 在理解闭包以前.最好能

js中的闭包理解一

闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的理解以及js内部解释器的运作方式的描述,都是可以看出你js实际水平的.即使你没答对,也能让考官对你的水平有个评估.那么我先来说说我对js中的闭包的理解. 闭包是很多语言都具备的特性,在js中,闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等. 在理解闭包以前.最好能

JS中&&和||的理解

运算符可以从三个不同的层次进行理解. 第一层理解 当操作数都是布尔值时,"&&"对两个值执行布尔与(AND)操作. 复制代码代码如下: x==0 && y==0 // 只有当x和y都是0时,才返回true 关系运算符的优先级比"&&"要高. 第二层理解 "&&"可以对真值和假值进行布尔与(AND)操作.(假值有false.null.undefined.0.NaN和"&quo

对JS中函数的理解

函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能) var fn=function(a){return a+100;} fn=function(a){return a+200;} alert(fn(100)); //300 要访问函数的引用(指针)而不是执行函数时,必须去掉圆括号,加上圆括号表示访问函数执行后的结果 函数体内部的语句在执行时,一旦

浅谈js中继承的理解和实现

一.前言 java.C#等正统面向对象语言都会提供类似extend之类的处理类的继承的方法,而javascript并没有提供专门的方法用于继承,在javascript中使用继承需要一点技巧.js中实例的属性和行为是由构造函数和原型两部分组成的,js的继承也分为这两部分.下面给大家分享一下在js中如何实现继承,讲的不对的地方望大家指正! 二.继承构造函数中的属性和行为 我们定义两个类Animal和Bird类,来实现js中类的继承. //定义Animal类 function Animal(name)

js中数据类型的理解

1.js中的基本数据类型:String.Number.Boolean.Null和Undefined,还有一种复杂数据类型Object. 2.对于Null和Undefined的不同,现在的JavaScript设计为Null表示'无'的对象,转为数值0:undefined未定义,转为数值NaN.其中NaN的数据类型为number,意为Not a Number;当两种不同的数据的类型相运算时则要注意一些细节,自己总结了一点: 所有和undefined有关的运算,返回的为NaN:  Null + 0 =