JavaScript异常处理总结

原创 2017年06月20日 08:43:30

使用抛出异常机制能让代码结构更加的简洁,减少很多的逻辑判断,并且能够得到出错时的详细错误信息,可说是好处多多,今天要说的就是在js中抛出(throw)异常。


一、语法

1. 可以抛出任何类型的异常,比如数字、字符串甚至布尔值

<script>
    try {
        throw 'error';
        throw 123;
        throw false;
    }
    catch (e) {
        alert(e);
    }
</script>

2. 可以抛出自定义的对象

<script>
    function CommonException(message, code) {
        this.message = message;
        this.code = code;
    }
    try {
        var exception = new CommonException('您的代码出错啦', 1);
        throw exception;
        alert('这地方的代码将不会执行到');
    } catch (e) {
        alert(e.message);
        alert(e.code)
    }
</script>

3. 内置的异常类Error

    new Error([message[, fileName[, lineNumber]]])  

Error具有下面一些主要属性:

  • 第一个参数代表错误提示信息(message)
  • 第二个是文件名
  • 第三个是行号。

简单示例:

<script>
    try {
        throw new Error('Whoops!');
    } catch (e) {
        alert(e.name + ': ' + e.message);
    }
</script>

4. 自定义异常类并继承Error基类

<script>
    // Create a new object, that prototypically inherits from the Error constructor
    function MyError(message) {
        this.name = 'MyError';
        this.message = message || 'Default Message';
        this.stack = (new Error()).stack;
    }
    /*prototype是什么含义?*/
    /*javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。*/
    /*A.prototype = new B();*/
    /*理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。
    这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。*/
    MyError.prototype = Object.create(Error.prototype);
    MyError.prototype.constructor = MyError;

    try {
        throw new MyError();
    } catch (e) {
        alert(e.name);     // 'MyError'
        alert(e.message);  // 'Default Message'
    }

    try {
        throw new MyError('custom message');
    } catch (e) {
        alert(e.name);     // 'MyError'
        alert(e.message);  // 'custom message'
    }
</script>

5. 捕获处理特定的错误类

<script>
    try {
        throw RangeError("测试");
    } catch (e) {
        if (e instanceof EvalError) {
            alert(e.name + ': ' + e.message);
        } else if (e instanceof RangeError) {
            alert(e.name + ': ' + e.message);
        } else if (e instanceof MyError) {
            alert(e.name + ': ' + e.message);
        } else {
            // etc...
        }
    }
</script>

二、常见异常类型

1. SyntaxError - 解析错误

SyntaxError是解析代码时发生的语法错误

// 变量名错误
var 1a;
// 缺少括号
console.log 'hello');

2. ReferenceError - 引用错误

ReferenceError是引用一个不存在的变量时发生的错误。将一个值分配给无法分配的对象,比如对函数的运行结果或者this赋值。

a
// Uncaught ReferenceError: a is not defined
this=1;
// Uncaught ReferenceError: Invalid left-hand side in assignment
new abc
// Uncaught ReferenceError: abc is not defined(…)

3. RangeError - 范围错误

RangeError是当一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。

new Array(-1)
// Uncaught RangeError: Invalid array length(…)
(1234).toExponential(21)//toExponential() 方法可把对象的值转换成指数计数法。参数为小数位0~20
// Uncaught RangeError: toExponential() argument must be between 0 and 20(…)

4. TypeError - 类型错误

TypeError是变量或参数不是预期类型时发生的错误。比如,使用new字符串、布尔值、数值等原始类型和调用对象不存在的方法就会抛出这种错误,因为new命令的参数应该是一个构造函数。

new 1
// Uncaught TypeError: 1 is not a constructor(…)
var obj = {}; obj.a()
// Uncaught TypeError: obj.a is not a function(…)

5. URIError - 统一资源标识符函数错误

URIError是URI相关函数的参数不正确时抛出的错误。
主要涉及encodeURI()decodeURI()encodeURIComponent()decodeURIComponent()escape()unescape()这六个函数。

decodeURI('%1')
// Uncaught URIError: URI malformed(…)

6. EvalError - eval()函数执行错误

eval()函数没有被正确执行时,会抛出EvalError错误。该错误类型已经在ES5中不使用了,只是为了保证与以前代码兼容,才继续保留。

小结

以上这6种派生错误,连同原始的Error对象,都是JavaScript自带的构造函数。
开发者可以使用它们,人为生成错误对象的实例。
例一:

new Error("出错了!");

例二:

new RangeError("出错了,变量超出有效范围!");

例三:

try {
    null.f();
} catch (e) {
    throw new SyntaxError("解析出错了!");
}

三、使用案例

场景

有这样一个场景,我们在一个业务系统中,经常需要做表单元素的校验,比如:

var username = $("#username").val();
var password = $("#password").val();
if (username.length < 6) {
    alert(“用户名长度不能小于6”);
    return;
}
if (password.lengt < 6) {
    alert(“密码长度不能小于6”);
    return;
}
// ... ...

系统中到处都有类似这样的长度校验代码,我们会想能不能定义一个公共的方法进行校验,所以我们写了如下的方法:

function checkLength (str, len, msg) {
    if (str.lengt < len) {
        alert(msg);
        return;
    }
}

var username = $("#username").val();
var password = $("#password").val();
checkLength(username, 6, “用户名长度不能小于6”);
checkLength(username, 6, “密码长度不能小于6”);
// ... ...

写完上面的代码我们会发现并不能达到我们的目的,因为校验失败的话程序并不会终止。

解决方案

我们可以在校验方法里抛出一个异常强制终止程序。

function checkLength (str, len, msg) {
    if (str.lengt < len) {
        alert(msg);
        throw Error(msg);
    }
}

这样就达到了我们想要的效果。


四、总结

JavaScript 拥有基本的异常处理方法,但是一般前端工程师都不会处理异常。
其实情有可原,对于普通网站来说,异常是非常可控的,基本可以刷新页面就解决问题,运行环境+代码运行也很少带来异常。
但是对于业务富集的webApp/大型组件来说,没有异常处理会是异常灾难。
无论在用户使用场景或者在开发/调试 作为出发点,异常处理都是非常必要的异常处理非常重要,它可以提高程序健壮性,对于软件开发来说,健壮性是非常重要的一项指标。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

JavaScript错误与异常处理

  • 2011-07-20 00:27
  • 219KB
  • 下载

javaScript异常处理文档

  • 2015-11-19 21:23
  • 33KB
  • 下载

【javaScript基础】异常处理

理解异常在javaScript面向对象编程是非常重要的,异常是一种非常强大的处理错误的方式。 错误处理          首先我们来看一个有问题的代码: nonexistant(); 在以上这...

JavaScript异常处理

  • 2014-12-21 12:08
  • 28KB
  • 下载

2014年辛星Javascript解读第五节 break continue 与异常处理

先说一下break和continue的主要用法吧,break用于跳出循环,continue用于跳过该循环中的一个迭代。简单的说,就是break直接从该语句跳出,但是continue不会跳出该循环语句,...

javascript中的异常处理

try catch finally是javascript语言提供的异常处理机制。语法结构如下       try    {             trySt...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)