有时候,在自己封装的工具函数中,不传参或传入了错误类型的参数,也要适当的抛出一些错误以示警告;使用框架不正常情况下也会抛出错误,如果对错误一无所知,便无从下手调试。综合上述,了解错误的处理机制是多么必要。

以下是笔者归纳总结,如有误之处,欢迎指出。

错误构造函数

javascript规范中总共有8中错误类型构造函数

  • Error -- 错误对象

  • SyntaxError --解析过程语法错误

  • TypeError -- 不属于有效类型

  • ReferenceError -- 无效引用

  • RangeError -- 数值超出有效范围

  • URIError -- 解析URI编码出错

  • EvalError -- 调用eval函数错误

  • InternalError -- Javascript引擎内部错误的异常抛出, "递归太多"

其中两种做个特殊说明:

EvalError调用eval函数错误,已经弃用,为了向后兼容,低版本还可以使用。
InternalError 递归过深 抛出错误,多数浏览器未实现,属于非标准方法,生产环境禁用

继承关系

Error是错误的基类,其他类型都继承Error这个类,可以使用ES6中提供的Object.getPrototypeOf()来判断,一个类是否继承了另一个类。

console.log(Object.getPrototypeOf(SyntaxError) === Error);    // true

console.log(Object.getPrototypeOf(TypeError) === Error);   // true

console.log(Object.getPrototypeOf(RangeError) === Error);   // true

console.log(Object.getPrototypeOf(URIError) ===  Error);   // true

console.log(Object.getPrototypeOf(EvalError) === Error);   // true

console.log(Object.getPrototypeOf(ReferenceError) === Error); // true

来聊一聊每一种错误类型的使用和出错的场景。

Error

通过Error的构造器可以创建一个错误对象。当运行时错误产生时,Error的实例对象会被抛出。

语法:new Error([message])

参数:

message 可选,错误描述信息。

抛出错误

使用throw语句来抛出异常

throw new Error('这里抛出的是错误信息')

运行后,会在控制台打印输出:

Uncaught Error: 这里抛出的是错误信息

注意: 使用 throw 抛出异常后,之后的代码不再执行。

捕获错误

可以通过try{}catch(){}语句来捕获到这个错误

try{    throw new Error('这里抛出的是错误信息')
}catch(err){
alert(err.name + ' '+ err.message)
}

属性说明:
     当使用new Error创建错误实例后,会有两个属性:

let e = new Error('这里抛出的是错误信息');

name属性,为错误的类型,此时为Error
message属性,为错误的信息,此时为'这里抛出的是错误信息'

SyntaxError

解析过程语法错误,这种类型抛出的错误有很多,往往是书写时候造成的语法错误,例如:

let n = 1\1;   // Uncaught SyntaxError: Invalid or unexpected token
let str = "hel"lo" // Uncaught SyntaxError: Unexpected identifier
let 123Var = 'hi' // Uncaught SyntaxError: Invalid or unexpected token

语法错误有很多就不一一列举了,当在浏览器运行时,控制台会抛错,并且告知第几行,所以调试器来比较方便。但要读懂错误的类型为SyntaxError,以及后面的错误信息,这样方便改错。

TypeError

不属于有效类型。这种错误就是在给的不是需要的类型而导致无法操作,会抛出类型错误。

变量或参数不是预期类型,

  • 变量或参数不是预期类型

例如**new**运算符后必须是函数,而给定的不是函数,则会抛出类型错误

let fn = 'hello';
new fn;

抛出错误:

Uncaught TypeError: fn is not a constructor
  • 调用对象不存在的方法

let obj = {};
obj.fn()

抛出错误:

Uncaught TypeError: obj.fn is not a function

当然你也可以在封装函数时候,强制传入的参数为指定类型,否则抛出类型错误。

function flatten(arr){    if( !Array.isArray(arr) ){        throw new TypeError('传入参数不是数组')
}
}
flatten('test');

传入的参数不为数组时,抛出自定义的类型错误:

Uncaught TypeError: 传入参数不是数组

ReferenceError

无效引用。

引用了一个不存在的变量

console.log(a);

抛出错误

Uncaught ReferenceError: a is not defined
  • 将变量赋值给一个无法被赋值的数据
    这个错误常常犯的地方实在调用一个方法后在if语句中做判断,将比较运算符==写成了赋值运算符=,例如判断一个字符串第一个字符是不是指定的字符:

let str = 'hello';if( str.charAt(0) = 'h' ){
console.log('第一个字符为h');
}

抛出错误:

Uncaught ReferenceError: Invalid left-hand side in assignment

RangeError

数值超出有效范围。在一些方法中,传入的数值必须在一定的范围内,否则会抛出超出范围的错误。

  • 创建数组传入的长度小于了0

let arr = new Array(-1)

抛出错误:

Uncaught RangeError: Invalid array length
  • repeat方法重复指定的字符串重复次数小于0

let str = 'hello';
str.repeat(-1)

抛出错误:

Uncaught RangeError: Invalid count value

URIError

处理URI编码出错。函数参数不正确,主要是encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。

例如:

decodeURIComponent('%');
decodeURI('%2')

抛出错误:

Uncaught URIError: URI malformed

自定义错误类型

有时候希望自定义错误类型,需要自定义一个构造函数,然后让原型继承继承Error.prototype即可。

function MyErrorType(message){
this.message = message || '错误';
this.name = 'MyErrorType';
this.stack = (new Error()).stack; // 错误位置和调用栈
}
MyErrorType.prototype = Object.create(Error.prototype);
MyErrorType.prototype.constructor = MyErrorType;
throw new MyErrorType('自定义错误类型抛出错误')

关于调用的错误栈信息

提供的错误的跟踪功能,以什么样的调用顺序,在哪个文件的哪一行捕获到这个错误。
例如以下调用:

function trace() {
try {
throw new Error('myError');
}
catch(e) {
console.log(e.stack);
}
}
function b() {
trace();
}
function a() {
b(3, 4, '\n\n', undefined, {}); }
a('first call, firstarg');

错误信息为:

Error: myError
at trace (<Error.html>:3:14)
at b (<Error.html>:10:6)
at a (<Error.html>:13:6)
at <Error.html>:15:4

以上为抛错的构造函数的总结,如有误之处欢迎扶正。
以上每一种错误场景并没有列出太多,如果你有新的错误信息发现,欢迎留言讨论。

究竟 javascript 错误处理有哪些类型?的更多相关文章

  1. javascript 核心语言笔记- 3 - 类型、值和变量

    JavaScript 中的数据类型分为两类:原始类型(primitive type)和对象类型(object type).原始类型包括数字.字符串和布尔值 JavaScript 中有两个特殊的原始值: ...

  2. 01.JavaScript 面向对象精要--原始类型和引用类型

    一.什么是类型 JavaScript 虽然没有类的概念.但依然存在两种类型:原始类型和应用类型. 原始类型保存为简单的数据值,引用类型则保存为对象,其本质是指向内存位置 的引用.也就是说:原始值被直接 ...

  3. javascript错误处理与调试(转)

    JavaScript 在错误处理调试上一直是它的软肋,如果脚本出错,给出的提示经常也让人摸不着头脑. ECMAScript 第 3 版为了解决这个问题引入了 try...catch 和 throw 语 ...

  4. JavaScript错误处理

    JavaScript 错误 - Throw.Try 和 Catch JavaScript 测试和捕捉 try 语句允许我们定义在执行时进行错误测试的代码块. catch 语句允许我们定义当 try 代 ...

  5. 第一百二十三节,JavaScript错误处理与调试

    JavaScript错误处理与调试 学习要点: 1.浏览器错误报告 2.错误处理 3.错误事件 4.错误处理策略 5.调试技术 6.调试工具 JavaScript在错误处理调试上一直是它的软肋,如果脚 ...

  6. 1000多个项目中的十大JavaScript错误以及如何避免

    通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个.下面会向大家介绍这些错误发生的原因以及如何防止. 对于这些错误发生的次数,我们是通过收集的数据统计得出的 ...

  7. 【转】Javascript错误处理——try…catch

    无论我们编程多么精通,脚本错误怎是难免.可能是我们的错误造成,或异常输入,错误的服务器端响应以及无数个其他原因. 通常,当发送错误时脚本会立刻停止,打印至控制台. 但try...catch语法结构可以 ...

  8. 【转】JavaScript 错误处理与调试——“错误处理”的注意要点

    try-catch语句 该语句最适合处理那些我们无法控制的错误,在明明白白地知道自己的代码会发生错误时,再使用该语句就不太合适了. ECMA-262第3版引入了try-catch语句,基本的语法如下所 ...

  9. C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断

    C#保留2位小数几种场景总结   场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...

随机推荐

  1. Vue.js表单校验;动画指令;避免内存泄露。

    Vue.js表单校验: 动画指令:创建自定义的滚动指令. 避免内存泄露. 避免内存泄露 在单页面应用开发时SPA,用户无需刷新浏览器.所以javascript应用需要自行清理组件来防止内存占用不断增长 ...

  2. RMQ 解决区间查询问题

    线段树写法不管,比较灵活.这里主要讨论DP实现. 其实单纯说RMQ解决的是区间最值查询是不准确的,只要满足一个区间的信息可以从它的覆盖区间获得(即[L,R]<=[L,r],[l,R] (l< ...

  3. scrapy-redis(一)

    安装scrapy-redis pip install scrapy-redis 从GitHub 上拷贝源码: clone github scrapy-redis源码文件 git clone https ...

  4. IntelliJ IDEA2017创建web工程并实现远程部署tomca【转载】

    [IntelliJ IDEA2017创建web工程并实现远程部署tomcat] 作者:https://segmentfault.com/a/1190000012762629 将应用打成war包方式 步 ...

  5. Hadoop--Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Starting namenodes on [localhost]

    Unable to load native-hadoop library for your platform... using builtin-java classes where applicabl ...

  6. 【转】Entity Framework Extended Library (EF扩展类库,支持批量更新、删除、合并多个查询等)

    E文好的可以直接看https://github.com/loresoft/EntityFramework.Extended 也可以在nuget上直接安装这个包,它的说明有点过时了,最新版本已经改用对I ...

  7. Vue.js 引入外部js方法

    1.外部文件config.js 第一种写法 //常量的定义 const config = { baseurl:'http://172.16.114.5:8088/MGT2' } //函数的定义 fun ...

  8. struts项目部署在Tomca上在断网情况下启动报错

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6015693.html 前段时间,项目部署到现场后,反馈Tomcat能正常启动,但是项目有时访问不了也不报错. ...

  9. Java并发机制及锁的实现原理

    同步的基本思想 为了保证共享数据在同一时刻只被一个线程使用,我们有一种很简单的实现思想,就是 在共享数据里保存一个锁 ,当没有线程访问时,锁是空的. 当有第一个线程访问时,就 在锁里保存这个线程的标识 ...

  10. CentOS下安装mysql5.7和mysql8.x

    5.7和8.15版本亲测.centos版本为:CentOS-7-x86_64-Minimal-1810. 1.下载mysql57-community-release-el7-9.noarch.rpm. ...