JavaScript Error对象及错误类型

 2016年07月17日    125     声明


Error是JavaScript中的错误类,它同时也是一个构造函数,可以用来创建一个错误对象。Error实例会在发生运行进错误时抛出,Error像其它对象一样,也可以由用户自定义创建。

  1. Error对象
  2. JavaScript中的错误类型

1. Error对象

1.1 语法结构

ECMAScript语言标准中规定,创建Error实例的语法结构如下:

new Error ([message])

构造函数只包含一个参数:

  • message - 可选,表示错误描述

不同执行引擎对Error类的实现有所不同,如:火狐还添加了两额外的可选参数,分别表示发生错误文件名和发生错误的行号:

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


1.2 Error类方法与属性

方法

Error类本身没有任何方法。但是,在JavaScript中所有类都是Object的子类,所以其会包含一些继承自Object的类方法。

属性

Error类也没有自身定义的类属性,其所有属性据来自于其父类Object

  • Error.prototype - 添加到实例中的属性


1.3 Error实例

运行时错误实例会由执行引擎自动创建和抛出,我们也可以通过构造函数自定义Error实例,与其它类一样我们也可以通过Error.prototype向实例中添加属性和方法。

Error实例包含以下属性或方法:

  • Error.prototype.constructor - 指定对象的构造函数
  • Error.prototype.message - 错误信息
  • Error.prototype.name - 错误名
  • Error.prototype.stack - 错误堆栈信息。该属性是一个非标准属性,但被大多数执行引擎所支持。
  • Error.prototype.toString() - 表示错误对象的描述信息。继承并重写Object.prototype.toString()


1.4 Error使用示例

通常,可以在创建Error实例后,通过throw关键字抛出。和大多数语言一样,JavaScript提供了try...catch结构来捕获和处理错误:

try {
  throw new Error('Whoops!');
} catch (e) {
  console.log(e.name + ': ' + e.message);
}

捕获错误后,可以通过instanceof关键字来判断错误类型:

try {
  foo.bar();
} catch (e) {
  if (e instanceof EvalError) {
    console.log(e.name + ': ' + e.message);
  } else if (e instanceof RangeError) {
    console.log(e.name + ': ' + e.message);
  }
  // ... etc
}

当JavaScript内置错误类型不能满足需要时,还可以自定义错误。自定义错误就是继承Error对象,并对其进行一定的扩展:

// 创建一个新对象,并以原型链的方式 Error 
function MyError(message) {
  this.name = 'MyError';
  this.message = message || 'Default Message';
  this.stack = (new Error()).stack;
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;

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

try {
  throw new MyError('custom message');
} catch (e) {
  console.log(e.name);     // 'MyError'
  console.log(e.message);  // 'custom message'
}


2. JavaScript中的错误类型

除标准错误对象Error外,JavaScript中还内置了一些类型错误对象。它们会在特殊时刻,或由特定的对象触发。

2.1 EvalError - Eval错误

EvalError对象表示全局函数eval()中发生的错误。如果eval()中没有错误,则不会抛出该错误。同样可以通过构造函数创建这个对象的实例:

new EvalError([message])

如:抛出一个EvalError异常:

try {
  throw new EvalError('itbilu.com');
} catch (e) {
  console.log(e instanceof EvalError); // true
  console.log(e.message);              // "itbilu.com"
  console.log(e.name);                 // "EvalError"
  console.log(e.stack);                // "EvalError: itbilu.com…"
}


2.2 ReferenceError - 引用错误

ReferenceError错误对象会在引用未定义的变量时触发。也可以通过构造函数创建该对象的实例:

new ReferenceError([message])

引用未定义的变量时,会抛出该错误:

try {
  var a = undefinedVar;
} catch (e) {
  console.log(e instanceof ReferenceError); // true
  console.log(e.message);                   // "undefinedVar is not defined"
  console.log(e.name);                      // "ReferenceError"
  console.log(e.stack);                     // "ReferenceError: undefinedVar …"
}

也可以通过构造函数创建该对象实例:

try {
	throw new ReferenceError('Hello');
} catch (e) {
  console.log(e instanceof ReferenceError); // true
  console.log(e.message);                   // "Hello"
  console.log(e.name);                      // "ReferenceError"
  console.log(e.stack);                     // "ReferenceError: Hello …"
}


2.3 RangeError - 范围错误

RangeError错误对象会在值超过有效范围时触发。也可以通过构造函数创建该对象的实例:

new RangeError([message])

触发RangeError错误的情况有:对Array构造函数使用错误的长度值,对Number.toExponential()Number.toFixed()Number.toPrecision()使用无效数字等。

var check = function(num) {
  if (num < 0) {
    throw new RangeError('传入值需要大于 0');
  }
};

try {
	check(-1);
}
catch (e) {
	console.log(e instanceof RangeError); // true
	console.log(e.name);									// RangeError
	console.log(e.message);              // 传入值需要大于 0
}


2.4 SyntaxError - 语法错误

SyntaxError错误对象会使用不合法的语法结构时触发。也可以通过构造函数创建该对象的实例:

new SyntaxError([message])

如,可以像下面这样创建并捕获语法错误:

try {
  throw new SyntaxError('Hello');
} catch (e) {
  console.log(e instanceof SyntaxError); // true
  console.log(e.message);                // "Hello"
  console.log(e.name);                   // "SyntaxError"
}


2.5 TypeError - 类型错误

TypeError错误会在对象用来表示值的类型非预期类型时触发。也可以通过构造函数创建该对象的实例:

new TypeError([message])

如,可以像下面这样捕获类型错误:

try {
  null.f();
} catch (e) {
  console.log(e instanceof TypeError); // true
  console.log(e.message);              // "null has no properties"
  console.log(e.name);                 // "TypeError"
}


2.6 URIError - URI错误

URIError错误会错误使用全局URI函数如encodeURI()decodeURI()等时触发。也可以通过构造函数创建该对象的实例:

new TypeError([message])

如,可以像下面这样捕获URI错误:

try {
  decodeURIComponent('%');
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message);             // "URI malformed"
  console.log(e.name);                // "URIError"
}