JavaScript异常

javascript异常

所谓异常就是程序的非正常运行,通俗的说就是程序发生了错误。至于这些错误,有的是认为疏忽造成的异常(Exception),有的是程序本身的错误(Error)。

比如有的时候我们希望两个数相加,因为人为疏忽,代码里写成了乘号,那么这种错误大部分情况下是得不到你想要的结果的,但是幸运又不幸的是,这个程序没有语法错误,依然可以返回结果,但是无法报错。

另一种情况就是你的程序无法被JavaScript引擎执行,这种异常引擎会抛出一个异常,这个时候如果你没有捕获异常,那么程序就会被中断,无法执行下去。

code1:

alert('js运行了!')
let a = b + 1
alert('程序结束')
pic1

这个时候我们的浏览器客户端作为JavaScript引擎就会捕获一条异常报告,俗称报错了。
因为此时代码中的 b 是尚未定义的,抛出了ReferenceError这个异常,下面是JavaScript中经常遇到的异常类型,大概分类有如下几种:

  • EvalError: raised when an error occurs executing code in eval()
  • RangeError: raised when a numeric variable or parameter is outside of its valid range
  • ReferenceError: raised when de-referencing an invalid reference
  • SyntaxError: raised when a syntax error occurs while parsing code in eval()
  • TypeError: raised when a variable or parameter is not a valid type
  • URIError: raised when encodeURI() or decodeURI() are passed invalid parameters

上面的六种异常对象都继承自Error对象。他们都支持以下两种构造方法: new Error();
new Error(“异常信息”);

try/catch/finlly语句

上面介绍了几种程序抛出的异常,那么现在就需要对异常进行处理,其中try从句中定义了需要处理和判断的代码块,catch从句中放置当程序发生异常后进行处理的代码,catch从句后跟随finally块,finally中放置清理代码,不管try块中是否产生异常。finally块中的逻辑代码都会执行,其中catch和finally都是可选的,但是必须选择两种中之一和try从句组成完整的语句。
try、catch、finally语句块都需要使用花括号括起来,即使语句中只有一条语句也不能省略,记住,这里的花括号是必须的

下面的代码说明了try/catch/finlly语句的用法和作用

try {
    // 这里是你可能会出现异常的代码
    //  可以通过throw直接抛出异常
    // 或者通过调用一个方法间接抛出
} catch(e) {
    // 当try语句块抛出了异常,这里的代码就会执行
    // 可以通过局部变量e来获取该异常Error对象的信息
    // 可以通过throw重新抛出异常
} finally {
    // 无论是否抛出异常,都会执行这里的代码
    // 终止语句块的方法有:
    // 1. 正常执行最后一条语句终止
    // 2. 通过break、continue、或return终止
    // 3. 抛出异常,被try捕获
    // 4. 抛出异常,异常未被捕获,继续向上传播
}

我们看到,catch后面接了个标识符e,这个标识符和函数参数很想,当捕获一个异常时,把和这个异常相关的值(比如Error对象)赋值给这个参数,和普通的变量不同,这条catch句中的标识符具有块级作用域,它只在catch语块内有定义。这个Error对象有几个主要属性,如下:

  • description: 错误描述 (仅IE可用).
  • fileName: 出错的文件名 (仅Mozilla可用).
  • lineNumber: 出错的行数 (仅Mozilla可用).
  • message: 错误信息 (在IE下同description)
  • name: 错误类型.
  • number: 错误代码 (仅IE可用).
  • stack: 像Java中的Stack Trace一样的错误堆栈信息 (仅Mozilla可用).

下面就使用一个try/catch语句把pic1中的代码包裹起来

try{
    //这里放置可能会出错的代码
    let a = b + 1
} catch(e)
{
    //代码出错后执行这里。
    console.debug(' name: ' + e.name +  
          ' message: ' + e.message +  
          ' lineNumber: ' + e.lineNumber +  
          ' fileName: ' + e.fileName +  
          ' stack: ' + e.stack);  
} finally {
    console.log('执行了finally')
}

将上面的代码复制到chrome控制台,会看到下面的信息,说明异常已经被捕获,并且,最终执行了finally


pic2

通常状况下,解释器执行到try语句块的尾部,然后开始执行finally中的代码,以便进行必要的清理工作。当由于return、continue、break语句使得解释器跳出try语句块时,解释器在执行新的目标代码之前先执行finally中的代码。

如果在try中产生了异常,而且存在一条与之相关的catch从句来处理这个异常,解释器首先执行catch中的逻辑,然后执行finally中的逻辑,如果不存在处理异常的局部catch从句,解释器会首先执行finally中的逻辑,然后向上传播异常,直到找到能处理这个异常的catch从句。

如果finally快使用了return、continue、break或者throw语句时程序发生跳转,或者通过调用了抛出异常的方法改变了程序执行流程,不管这个跳转使程序挂起还是继续执行,解释器都会将其忽略。例如finally从句抛出一个异常,这个异常将替代正在抛出的异常。如果finally从句运行倒了return语句,尽管已经抛出了异常且这个异常还没有处理,这个方法依然会正常返回。

throw语句

在JavaScript运行的时候,若使用throw语句时就会电视的抛出异常。
throw语句的语法如下:

throw expression

expression的值是任意类型的。可以抛出代表错误码的数字亦或是让人明白意思的字符串。JavaScript解释器抛出异常的时候通常采用Error类型和其子类型。

function getMoney(money) {
    // 若传入的参数非法,直接抛出异常
    if (money < 0) 
        throw new Error('金额不能为负数')
    return money
}

在chrome控制台里试试,这个时候如果传入的参数小于0就会直接抛出一个自定义字符串的异常了,见下图:

pic#

最后

当程序抛出异常时,JavaScript解释器会立即停止当前正在执行的逻辑,并跳转至就近的异常处理程序,如果抛出异常的代码块中没有try/catch语句,解释器会检查更高层次的闭合代码块,看它是否有关联异常处理程序。以此类推,直到找到异常处理程序为止

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容