当JavaScript 引擎执行 JavaScript 代码时,会发生各种错误:可能是语法错误,通常是程序员造成的编码错误或错别字;可能是拼写错误或语言中缺少的功能(可能由于浏览器差异);可能是由于来自服务器或用户的错误输出而导致的错误;也可能是由于许多其他不可预知的因素。那么js有没有好的可以检测错误的呢?

JS本身是动态语言,因此人们普遍认为它是一种最难于调试的编程语言。脚本出错时,由于没有上下文信息,让人摸不着头脑,ECMAScript 第 3 版致力于解决这个问题,专门引入了try-catch和throw等语句以及一些错误类型,意在让开发人员能够适当地处理错误,提升开发效率。

1. Error 实例对象

JavaScript 解析或运行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScript 原生提供Error构造函数,所有抛出的错误都是这个构造函数的实例。

var err = new Error('出错了');err.message // "出错了"

抛出Error实例对象以后,整个程序就中断在发生错误的地方,不再往下执行。

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

  • description: 错误描述 (仅IE可用).
  • fileName: 出错的文件名 (仅Mozilla可用).
  • lineNumber: 出错的行数 (仅Mozilla可用).
  • message: 错误信息 (在IE下同description)
  • name: 错误类型.
  • number: 错误代码 (仅IE可用).
  • stack: 像Java中的Stack Trace一样的错误堆栈信息 (仅Mozilla可用).

2. 原生错误类型

Error 实例对象是最一般的错误类型,在它的基础上,JavaScript 还定义了其他 6 种错误对象。也就是说,存在Error 的 6 个派生对象。

2.1 SyntaxError 对象

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

// 变量名错误  错误提示是“token 非法”var 1a;// Uncaught SyntaxError: Invalid or unexpected token// 缺少括号  错误提示是“字符串不符合要求”console.log 'hello');// Uncaught SyntaxError: Unexpected string

2.2 ReferenceError 对象

ReferenceError 对象是引用一个不存在的变量时发生的错误。

// 使用一个不存在的变量unknownVariable// Uncaught ReferenceError: unknownVariable is not defined

另一种触发场景是,将一个值分配给无法分配的对象。

// 等号左侧不是变量console.log() = 1// Uncaught ReferenceError: Invalid left-hand side in assignment// this 对象不能手动赋值this = 1// ReferenceError: Invalid left-hand side in assignment

2.3 RangeError 对象

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

// 数组长度不得为负数new Array(-1)// Uncaught RangeError: Invalid array length

2.4 TypeError 对象

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

new 123// Uncaught TypeError: number is not a funcvar obj = {};obj.unknownMethod()// Uncaught TypeError: obj.unknownMethod is not a function

2.5 URIError 对象

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

2.6 EvalError 对象

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

2.7 总结

以上这6种派生错误,连同原始的 Error 对象,都是构造函数。这些构造函数都接受一个参数,代表错误提示信息(message)。

var err1 = new Error('出错了!');var err2 = new RangeError('出错了,变量超出有效范围!');var err3 = new TypeError('出错了,变量类型无效!');err1.message // "出错了!"err2.message // "出错了,变量超出有效范围!"err3.message // "出错了,变量类型无效!"

3. throw 语句

throw 语句的作用是主动中断程序执行,抛出一个错误。

var x = -1if (x <= 0) {  throw new Error('x 必须为正数');}// Uncaught Error: x 必须为正数

上面代码中,如果变量 x 小于等于 0,就手动抛出一个错误,告诉用户 x 的值不正确,整个程序就会在这里中断执行。可以看到,throw 抛出的错误就是它的参数,这里是一个 Error 实例。

throw 可以抛出任何类型的值。也就是说,它的参数可以是任何值。

// 抛出一个字符串throw 'Error!';// Uncaught Error!// 抛出一个数值throw 42;// Uncaught 42

对于 JavaScript 引擎来说,遇到throw 语句,程序就中止了。引擎会接收到throw抛出的信息,可能是一个错误实例,也可能是其他类型的值。

4. try...catch 结构

一旦发生错误,程序就中止执行了。JavaScript 提供了 try...catch 结构,允许对错误进行处理,选择是否往下执行。

如果你不确定某些代码是否会报错,就可以把它们放在 try...catch 代码块之中,便于进一步对错误进行处理。

try {  throw "出错了";} catch (e) {  console.log(111);}console.log(222);// 111// 222

上面代码中,try 代码块抛出的错误,被catch代码块捕获后,程序不会中断,会按照正常流程继续执行下去。

5. finally 代码块

try...catch 结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。

function cleansUp() {  try {    throw new Error('出错了……');    console.log('此行不会执行');  } finally {    console.log('完成清理工作');  }}cleansUp()// 完成清理工作// Uncaught Error: 出错了……//    at cleansUp (:3:11)//    at :10:1

上面代码中,由于没有 catch 语句块,一旦发生错误,代码就会中断执行。中断执行之前,会先执行 finally 代码块,然后再向用户提示报错信息。

下面的例子说明,return 语句的执行是排在finally代码之前,只是等finally代码执行完毕后才返回。

var count = 0;function countUp() {  try {    return count;  } finally {    count++;  }}countUp()// 0count// 1// return语句里面的count的值,是在finally代码块运行之前就获取了。

下面的例子充分反映了 try...catch...finally 这三者之间的执行顺序。

function f() {  try {    console.log(0);    throw 'bug';  } catch(e) {    console.log(1);    return true; // 这句原本会延迟到 finally 代码块结束再执行    console.log(2); // 不会运行  } finally {    console.log(3);    return false; // 这句会覆盖掉前面那句 return    console.log(4); // 不会运行  }  console.log(5); // 不会运行}var result = f();// 0// 1// 3result// false

上面代码中,catch 代码块结束执行之前,会先执行 finally 代码块。

finally代码块用法的典型场景

openFile();try {  writeFile(Data);} catch(e) {  handleError(e);} finally {  closeFile();}

上面代码首先打开一个文件,然后在 try 代码块中写入文件,如果没有发生错误,则运行 finally 代码块关闭文件;一旦发生错误,则先使用 catch 代码块处理错误,再使用 finally 代码块关闭文件。




javascript出错 发生javascript错误_代码块