理解异常在javaScript面向对象编程是非常重要的,异常是一种非常强大的处理错误的方式。

错误处理

         首先我们来看一个有问题的代码:

  1. nonexistant();

在以上这个样例中,訪问一个不存在的变量,在这样的情况下,程序会怎么处理?非常早曾经的处理方式就是程序直接崩溃死掉,所以我们不能容忍这样的处理方式,须要有办法来处理。

    最简单的处理方式是先检查,像这样:

  1. if (window.func) {
  2. func();
  3. }

         上面这样的处理方式,仍然可能还会出现错误。

由于window.func可能不是一个函数。因此我们仍须要这样检查:

  1. if (typeof(func) == 'function') {
  2. func();
  3. }

在上面的样例中,typeof确保变量存在并确保是个函数。

         我们满怀希望地做了非常多须要的检查来确保运行func是安全的。可是假设func的函数体内有错误呢?我们更想做的是处理错误,而不是让程序死掉。

         我们能够用trycatch结构来处理。

Try catch 结构

         用try…catch来取代我们经常使用的if语句结构来处理错误,我们用例如以下代码来改写上面的样例:

  1. try {
  2. func()
  3. } catch(e) {
  4. alert(e)
  5. }

         假设在try块中出现错误,这个时候catch块会起作用,參数e被赋值为一个特别的异常对象。该对象包含异常发生时的一些信息。

         变量e是Error对象的一个实例(或者从TypeError,ReferenceError等继承)。

         这个错误的属性在不同浏览器有点不一样。详情參考Error in MDN 和 Error
inMSDN

可是基本属性是同样的:

name:错误类型,对于浏览器产生的error会匹配error构造函数如TypeError, ReferenceError 等。

message: 告诉我们更具体的error信息。

在下面样例中,我们在try块中添加其它声明,name和message会被打印出来。

  1. try {
  2. var a = 5
  3. var res = func(a)
  4. if (res > 0) doA()
  5. else doB()
  6. } catch(e) {
  7. alert("name:" + e.name + "\nmessage:" + e.message)
  8. }

非常多异常都能够被try..catch捕获,你仅需通过try来检測可能的错误即可了。

获取栈的信息

         Firefox,Chrome, Opera浏览器提供了stack属性,通过stack属性我们能够看到全部导致异常的嵌套的调用信息,样例例如以下:

  1. function f(a) {
  2. g(a+1)
  3. }
  4. function g(a) {
  5. notexists;
  6. }
  7. try { f(1) } catch(e) { alert(e.stack)

         不幸的是在IE中没有这个属性。甚至在IE9中也没有。

Try…catch…finally完整形式

         完整的组成形式是由3部分组成:

  1. try {
  2. .. try statemenets ..
  3. } catch(exception) {
  4. .. catch statements ..
  5. } finally {
  6. .. finally statements ..

运行步骤例如以下:

1. Try中的声明会被运行。假设没有发生错误,catch部分会被忽视。

2. 假设发生错误,exception变量会被赋值为错误对象。而且catch中的声明也会被运行。

3. 在以上两种情况下,在try或者catch中无论有没有运行,finally代码都会被运行。

try…catch…finally…return

在下面样例中,假设try中有return语句而且有finally块时,finally中的运行完后,运行return语句。

  1. function inc(a) {
  2. try {
  3. return a+1
  4. } catch(e) {
  5. // ..
  6. } finally {
  7. alert('done')
  8. }
  9. }
  10. alert( inc(1) )
  11. //运行结果:‘done’, 2

Throw声明

全部的错误能够被分成两种:

1. 程序设计错误:通常是由开发者造成的。如输入错误。

2. 异常流错误:这个错误是程序运行过程中的正常部分。一个常见的错误是表单验证。

假设用户输入了一些错误,正常的做法是处理这个错误而且叫用户反复输入。

         用try…catch来处理异常错误,须要通过throw手动抛出错误。

         语法是:throw e,e能够是不论什么东西。无论你抛出什么,都能够被catch…捕获,可是假设在try块外面抛出程序可能会崩溃。

         下面的样例展示了throw是怎样工作的。


  1. try {
  2. throw 5
  3. } catch(e) {
  4. alert("Caught: "+e)
  5. }

表单验证样例

         比如,我们对年龄进行验证,检查是否合法。

  1. function validateAge(age) { // age is a text to check
  2. if (age === '') return; // no age is valid
  3. age = +age
  4. if (isNaN(age)) {
  5. throw { name: 'BadAge', message: 'Invalid age' }
  6. }
  7. if (age < 5 || age > 150) {
  8. throw { name: 'BadAge', message: 'Age out of range' }
  9. }
  10. }
  11. try {
  12. var age = prompt("Enter your age please?")
  13. validateAge(age)
  14. alert("The age is accepted!")
  15. } catch(e) {
  16. alert("Error: "+e.message)
  17. }

经常来说。抛出的异常对象最好是从Error对象继承。提供一种更好的方式来管理error在上面的样例中应该这样实现:throw new BadAgeError("Invalid age")。

验证变化

如今假设须要加入一个验证条件,验证用户所提供的值是必须提供的。而且是有效的年龄。

比方我们实现了validateAge和validateRequired。

错误的检測方法

  1. var value = input.value
  2. // VALIDATE
  3. var error = validateRequired(value)
  4. if (!error) {
  5. error = validateAge(value)
  6. }
  7. if (!error) {
  8. /* another validator... */
  9. }
  10. // FINISHED VALIDATING
  11. if (error) {
  12. /* process error */
  13. } else {
  14. /* success */
  15. }

Try…catch方法

这样的方式就是当检測到错误时手动抛出。

  1. var value = input.value
  2. try {
  3. validateRequired(value)
  4. validateAge(value)
  5. // other validators in a row
  6. /* success */
  7. } catch(e) {
  8. /* process error */
  9. }

我们不须要一个一个地来检測,仅仅须要把可能出现错误的验证放到try块中即可了。假设一有错误。在catch中就会捕获到。没有错误自然非常顺利地运行。不会进入到catch块中。

比較

用try..catch处理错误有一些长处和缺点:

1. Try…catch方法处理错误更干净、简单可依赖,能够捕获全部错误。

2. 有可能存在一些不能检測的异常,try…catch是唯一能解决办法。

比如检測浏览器的一些特性。

3. Try…catch结构会占领几行代码的位置,看起来代码不太优雅。

异常分析和又一次抛出

         有时代码会产生不同的错误,这样的情况下,经经常使用if来选择正确的处理方式。下面是伪代码。

  1. try {
  2. // 1. do smth
  3. } catch(e) {
  4. if (e instanceof ValidationError) {
  5. // 2.1 process e
  6. } else if (e instanceof PermissionError) {
  7. // 2.2 process e
  8. } else {
  9. // 3. we don't know how to deal with e
  10. throw e
  11. }
  12. }

1. 在try块中的代码比較复杂,或许会抛出异常。有些异常我们知道怎么处理,比方ValidationError,可是其它一些异常不知道。

2. 在catch块中,我们分析异常而且处理它。

3. 否则。异常又一次抛出,假定在外面另一层try…catch块知道怎么处理该异常。

异常要么被又一次抛出,要么被处理。千万不要无论它。除非你全然知道你在做什么。

  1. try {
  2. func()
  3. } catch(e) {
  4. if (e instanceof KnownError) {
  5. // ...
  6. }
  7. }

在上面代码片段中。除了KnownError异常外,其它异常都被忽视了。

坦白地说。在java的世界里有这样的不处理异常的情况存在,可是留下不处理的异常总有隐患。

         想象下,假设在func中代码有输入错误,这将会非常难调试。由于TypeError 和ReferenceError 异常被忽视了。

总结

1. Try…catch…finally结构同意你在try块中加入几种声明,能够在各自的catch块中进行异常处理。

2.  同意处理全部错误。包含JS自己产生的和手动抛出的。

3.  严格来说javaScript同意throw不论什么值,可是推荐全部的错误继承Error对象,形成继承层级。在这样的情况下,instanceof 工作得非常好。比如你能够捕获全部e instanceof ValidationError的异常。ValidationError包含AgeValidationError, RequiredValidationError 等。

【javaScript基础】异常处理的更多相关文章

  1. 前端(十二)—— JavaScript基础操作:if语句、for循环、while循环、for...in、for...of、异常处理、函数、事件、JS选择器、JS操作页面样式

    JavaScript基础操作 一.分支结构 1.if语句 if 基础语法 if (条件表达式) { 代码块; } // 当条件表达式结果为true,会执行代码块:反之不执行 // 条件表达式可以为普通 ...

  2. JavaScript基础

    JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...

  3. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...

  4. Javascript基础知识总结一

    Javascript基础知识总结一 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  5. 第三篇:web之前端之JavaScript基础

    前端之JavaScript基础   前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript ...

  6. JavaScript基础知识(一)

    一.JavaScript基础 1.JavaScript用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 ...

  7. JavaScript 基础学习1-day14

    JavaScript 基础学习1 知识预览JavaScript概述二 JavaScript的基础三 JavaScript的对象BOM对象DOM对象实例练习js扩展 JavaScript概述 JavaS ...

  8. 2、JavaScript 基础二 (从零学习JavaScript)

     11.强制转换 强制转换主要指使用Number.String和Boolean三个构造函数,手动将各种类型的值,转换成数字.字符串或者布尔值. 1>Number强制转换 参数为原始类型值的转换规 ...

  9. JavaScript基础细讲

    JavaScript基础细讲   JavaScript语言的前身叫作Livescript.自从Sun公司推出著名的Java语言之后,Netscape公司引进了Sun公司有关Java的程序概念,将自己原 ...

  10. 学习笔记 第十五章 JavaScript基础

    第15章   JavaScript基础 [学习重点] 了解JavaScript基础知识 熟悉常量和变量 能够使用表达式和运算符 正确使用语句 能够掌握数据类型和转换的基本方法 正确使用函数.对象.数组 ...

随机推荐

  1. git 合并分支到master

    git 合并分支到master   假如我们现在在dev分支上,刚开发完项目,执行了下列命令 git add .git commit -m ‘dev'git push -u origin dev 然后 ...

  2. CSS多行文字超出隐藏加省略号

    overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 限制行数 overflow: hidden; text-overflow: ...

  3. bottle模板中的替换

    line是模板中一行的内容,类似: {{x}}testinfo{{x+10}} x=10时,模板输出: 10testinfo20 x = 10 splits = re.split(r'\{\{(.*? ...

  4. Hadoop学习------Hadoop安装方式之(二):伪分布部署

    要想发挥Hadoop分布式.并行处理的优势,还须以分布式模式来部署运行Hadoop.单机模式是指Hadoop在单个节点上以单个进程的方式运行,伪分布模式是指在单个节点上运行NameNode.DataN ...

  5. Python_在Ubuntu中搭建科学计算环境

    本文针对 Ubuntu 下搭建 Python 科学计算的环境,罗列了关键词和部分链接,最后附上了自己的一点分享. 1.升级 关键词: python ubuntu 升级 推荐: ubuntu16.04下 ...

  6. 删除Docker镜像

    删除镜像:1)先杀死镜像中所有容器   docker kill $(docker ps -a -q)2)删除镜像中所有容器:   docker rm $(docker ps -a -q)3)删除镜像: ...

  7. oracle 修改用户密码

    SYS用户是Oracle中权限最高的用户,而SYSTEM是一个用于数据库管理的用户.在数据库安装完之后,应立即修改SYS,SYSTEM这两个用户的密码,以保证数据库的安全. 安装完之后修改密码方法 c ...

  8. ssm登录与退出

    ssm整合比较好的实例 http://how2j.cn/k/ssm/ssm-tutorial/1137.html?tid=77#nowhere ssm登录后台用户检测(此实例注销有问题):http:/ ...

  9. 华莱士的 第一个python程序之(用户登录)

    Name = "shangzb"password = 43while True: _Name = input("Name:") if _Name == Name ...

  10. Golang的流程控制

    流程控制 条件语句 例: var b bool = true if b{ fmt.Print("b是True") }else{ fmt.Print("b是false&qu ...