Javascript Error 类分析

Error类的实例表示错误或异常,通常与throw语句和try/catch语句一起使用。属性name声明了异常的类型,message属性可以提供人们能够读懂的异常的详细信息。

JavaScritp解释器从不直接抛出Error对象,而是抛出Error子类(如SyntaxError或RangeError)的实例。

在用throw语句抛出错误时,则抛出Error对象,你会发现抛出Error对象指示异常非常方便,或者也可以用原始字符串或数字的形式抛出出错消息或出错代码。

以上是对Error类的描述,以前或许是没用到的缘故,一直没怎么关注它,这次将其整理出来,供有需要的人参考。

Error类

name属性

声明异常类型的字符串。对于Error类的实例和所有子类来说,该属性声明了用于创建实例的构造函数名。

因为

Function.prototype.name === '' //output 'true'

并且Function类是Error类的构造函数,所以Error类也有一个name属性,只不过构造Error类后,Error类将name属性的值定义为’Error’。

Error.name === 'Error'; //output 'true'

Error类的原型也默认有name属性,值也为’Error’,类似为下面的形式:

Error.prototype = {
  name : 'Error',
  ... native code
}

Error.name 与 Error.prototype.name 的值虽然是相同的,但其实是指向两块内存空间,更改任何一个name值并不会影响到另外的name值。

message属性

提供异常详细信息的出错消息。该属性存放传递给构造函数的字符串,或实现定义的默认字符串。

只有Error类的原型拥有message属性,且默认等于空,

Error.prototype.message === '' //output 'true'

内部实现类似为:

function Error(message) {
  this.mes = message || '';
}
Error.prototype = {
  message : this.mes,
  ... native code
}

toString方法

返回一个表示Error对象的字符串,该字符串由实现定义。

由于

Error.prototype.toString === Object.prototype.toString;
//output 'false'

所以Error的原型上重新定义了toString方法,类似下面的形式:

Error.prototype = {
  toString : function(){ [native code] },
  ... native code
}

返回值

新构造的Error对象。如果指定了参数message,该Error对象将它作为message属性的值;否则,它将用实现定义的默认字符串作为该属性的值。如果把Error()构造函数当作函数调用时不使用new运算符,它的行为与使用new运算符调用时一样。

至于有没有new运算符都可以新构造一个Error对象,这一点我没想明白是怎么实现的,或许是在 throw 上面”做的手脚”,还望高手指点。

例子:

function error(x) {
  if (x < 0) {
    try{
      throw Error("factorial: x must be >= 0");
    }
    catch(e) {
      alert(e.name + ' ' +e.message ) 
    }
  }
}
error(-1);

Error 类有六个子类:

EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。

由于这六个类,分别继承了Error类,所以也拥有message与name属性,并且也返回一个新构造的对象,也可以不使用new运算符。

EvalError类

当在其他名称下调用全局函数eval()时,EvalError类的一个实例就会被抛出。关于调用eval()函数的限制,请参阅“eval()”。

先占个位,回头有例子了再补上。

RangeError类

当数字超出合法范围时,RangeError类的一个实例就会被抛出。例如,把数组的length属性设置成一个负数,就会使RangeError对象被抛出。

例子:

/*
IE ------ RangeError:数组长度必须赋值为有限正数
Firefox - RangeError: invalid array length
*/
function error(x) {
  try {
    [].length = x;
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error(-1);

ReferenceError类

在读取一个不存在的变量的值时,ReferenceError类的一个实例就会抛出。

例子:

/*
IE ------ ReferenceError:'t'未定义
Firefox - ReferenceError: t is not defined
*/
function error(x) {
  try {
    alert(t);
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error();

SyntaxError类

SyntaxError类的一个实例会被抛出以通知JavaScript代码中的语法错误。eval()方法、Function()构造函数和RegExp()构造函数都可能抛出这种类型的异常。

例子:

/*
IE ------ SyntaxError:缺少')'
Firefox - SyntaxError: missing ) in parenthetical
*/
function error(x) {
  try {
    eval('({}');
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error();

TypeError类

当一个值的类型与要求不符时,TypeError类的一个实例就会被抛出。在访问值为null或nudefinde的属性时,这种情况经常发生。如果由一个对象(其他类的实例)调用另一个类定义的方法时,或者对于不是构造函数的值使用new运算符时,也会发生这种情况。当调用内部函数或方法时,如果传递的参数多于期望的个数,JavaScript的实现也允许招抛出TypeError异常。

例子:

/*
IE ------ TypeError: 'm'为空或不是对象
Firefox - TypeError: obj is nul
*/
function error(x) {
  try {
    var obj = null;
alert(obj.m) } catch(e) { if (e instanceof Error) { alert(e.name + ": " + e.message); } } } error();

URIError类

如果指定的字符串含有不合法的十六进制转义序列,则decodeURI()或decodeURIComponent()方法就会抛出URIError类的实例。如果指定的字符串含有不合法的Unicode替代对,encodeURI()或encodeURIComponent()方法也会抛出该异常。

例子:

/*
IE ------ URIError:被解码的URI不是合法的编码
Firefox - URIError: malformed URI sequence
*/
function error(x) {
  try {
    alert(decodeURI('%E4%B8%AR'));
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error();

下面再上一些例子,IE和Firefox抛出的Error子类对象均不同,到底哪个浏览器更准确些,自己判断喽~~~~

/*
IE ------ TypeError: 缺少对象
Firefox - ReferenceError: alertt is not defined
*/
function error(x) {
  try {
    alertt(x);
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error(1);
/*
IE ------ TypeError: 缺少')'
Firefox - ReferenceError: malformed formal parameter
*/
function error(x) {
  try {
    var newFunc = new Function('x','y+b','return x+y');
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error();
/*
IE ------ TypeError: 缺少对象
Firefox - TypeError: x is not a function
*/
function error(x) {
  try {
    x();
  }
  catch(e) {
    if (e instanceof Error) {
      alert(e.name + ": " + e.message);
    }
  }
}
error(1);
This entry was posted in Javascript/Ajax and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>