究竟 javascript 错误处理有哪些类型?

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

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


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

1、Error -- 错误对象

2、SyntaxError --解析过程语法错误

3、TypeError -- 不属于有效类型

4、ReferenceError -- 无效引用

5、RangeError -- 数值超出有效范围

6、URIError -- 解析URI编码出错

EvalError -- 调用eval函数错误

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

其中两种做个特殊说明:

EvalError调用eval函数错误,已经弃用,为了向后兼容,低版本还可以使用。

InternalError 递归过深 抛出错误,多数浏览器未实现,属于非标准方法,生产环境禁用

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


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

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 (:3:14)

at b (:10:6)

at a (:13:6)

at :15:4

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

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,149评论 0 13
  •   由于 JavaScript 本身是动态语言,而且多年来一直没有固定的开发工具,因此人们普遍认为它是一种最难于调...
    霜天晓阅读 763评论 0 1
  • 0. 写在前面 当你开始工作时,你不是在给你自己写代码,而是为后来人写代码。 —— Nichloas C. Zak...
    康斌阅读 5,323评论 1 42
  • Error 实例对象 JavaScript 解析或运行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScri...
    许先生__阅读 252评论 0 1
  • 1.压缩图片android:scaleType="fitXY" 2.锁定长宽比例缩放android:adjustV...
    Pomelo的笔记本阅读 191评论 0 0