JS 错误Error

一、 错误类型

摘录于JavaScript高级程序设计第四版

执行代码期间可能会发生的错误有多种类型。每种错误都有对应的错误类型,而当错误发生时,就
会抛出相应类型的错误对象。ECMA-262 定义了下列 8 种错误类型:

  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError
  • InternalError
    Error 是基类型,其他错误类型都继承自该类型。因此,所有错误类型共享相同的属性(错误对象中的方法全是默认的对象方法)。
  1. Error:Error类型的错误很少见,浏览器很少会抛出 Error 类型的错误;这个基类型的主要目的是供开发人员抛出自定义错误。
  2. EvalError: EvalError类型的错误会在使用 eval()函数而发生异常时被抛出。ECMA-262 中对这个错误有如下描述:“如果以非直接调用的方式使用 eval 属性的值(换句话说,没有明确地将其名称作为一个Identifier,即用作 CallExpression 中的 MemberExpression),或者为 eval 属性赋值。”简单地说,如果没有把 eval()当成函数调用,就会抛出错误,例如:
  new eval(); //抛出 EvalError
  eval = foo; //抛出 EvalError 
  在实践中,浏览器不一定会在应该抛出错误时就抛出 EvalError。例如,Firefox 4+和 IE8 对第一
  种情况会抛出 TypeError,而第二种情况会成功执行,不发生错误。有鉴于此,加上在实际开发中极
  少会这样使用 eval(),所以遇到这种错误类型的可能性极小。
  1. RangeError: RangeError类型的错误会在数值超出相应范围时触发。例如,在定义数组时,如果指定了数组不支持的项数(如-20 或 Number.MAX_VALUE),就会触发这种错误。下面是具体的例子。
  var items1 = new Array(-20); //抛出 RangeError 
  var items2 = new Array(Number.MAX_VALUE); //抛出 RangeError 
  RangeError 在 JavaScript 中发生得不多。
  1. ReferenceError:在找不到对象的情况下,会发生 ReferenceError(这就是著名的"object expected"浏览器错误的原因)。通常,在访问不存在的变量时,就会发生这种错误,例如:
  var obj = x; //在 x 并未声明的情况下抛出 ReferenceError
  1. SyntaxError:至于 SyntaxError,当我们把语法错误的 JavaScript 字符串传入 eval()函数时,就会导致此类错误。
  eval("a ++ b"); //抛出 SyntaxError 
  如果语法错误的代码出现在 eval()函数之外,则不太可能使用 SyntaxError,因为此时的语法错误会导致 JavaScript 代码立即停止执行。
  1. TypeError: TypeError在 JavaScript 中会经常用到,主要发生在变量不是预期类型,或者访问不存在的方法时。很多原因可能导致这种错误,尤其是在使用类型特定的操作而变量类型不对时。下面来看几个例子:
  var o = new 10; //抛出 TypeError 
  alert("name" in true); //抛出 TypeError 
  Function.prototype.toString.call("name"); //抛出 TypeError 
  最常发生类型错误的情况,就是传递给函数的参数事先未经检查,结果传入类型与预期类型不相符。
  1. URIError:在使用 encodeURI()或 decodeURI(),而 URI 格式不正确时,就会导致 URIError 错误。这种错误也很少见,因为前面说的这两个函数的容错性非常高。
  2. InternalError:会在底层 JavaScript 引擎抛出异常时由浏览器抛出。例如,递归过多导
    致了栈溢出。这个类型并不是代码中通常要处理的错误,如果真发生了这种错误,很可能代码哪里弄错
    了或者有危险了。

二 、错误事件

  1. js代码报错后会触发onerror 事件
//参数分别是错误消息、错误所在的 URL 和行号
window.onerror = function (message, url, line) { 
  console.log(message)
}
  1. 收集错误,可以使用Image对象来向服务器发送错误
function logError (sev, msg) { 
  var img = new Image()
  img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" +  encodeURIComponent(msg)
}
  • 所有浏览器都支持 Image 对象,包括那些不支持 XMLHttpRequest 对象的浏览器。
  • 可以避免跨域限制。通常都是一台服务器要负责处理多台服务器的错误,而这种情况下使用XMLHttpRequest 是不行的。
  • 在记录错误的过程中出问题的概率比较低。大多数 Ajax 通信都是由 JavaScript 库提供的包装函数来处理的,如果库代码本身有问题,而你还在依赖该库记录错误,可想而知,错误消息是不可能得到记录的。

三、错误处理与调试

  • 使用 try/catch 语句,可以通过更合适的方式对错误做出处理,避免浏览器处理。
try { 
 // 可能出错的代码
} catch (error) { 
 // 出错时要做什么
} 

注意:try/catch 语句还有一个finally 子句,如果 try 块中的代码运行完,则接着执行finally 块中的代码。如果出错并执行 catch 块中的代码,则 finally 块中的代码仍执行。try 或catch 块无法阻止 finally 块执行,包括 return 语句。比如:

function testFinally(){ 
   try { 
     return 2; 
   } catch (error){ 
     return 1; 
   } finally { 
     return 0; 
   } 
} 
最终结果无论成功或失败都会返回0。
只要代码中包含了 finally 子句,try 块或 catch 块中的 return 语句就会被忽略,理解这一点很重要。在使用 finally 时一定要仔细确认代码的行为
  • 通过分析代码预测很可能发生哪些错误。由于以下因素,JavaScript 中经常出现错误:
    1. 类型转换;
      类型转换错误的主要原因是使用了会自动改变某个值的数据类型的操作符或语言构造。使用等于
      (==)或不等于(!=)操作符,以及在 if、for 或 while 等流控制语句中使用非布尔值,经常会导致
      类型转换错误。
    2. 数据类型检测不足;
      因为 JavaScript 是松散类型的,所以变量和函数参数都不能保证会使用正确的数据类型。开发者需
      要自己检查数据类型,确保不会发生错误。数据类型错误常发生在将意外值传给函数的时候。
    3. 向服务器发送错误数据或从服务器接收到错误数据。
  • 代码调试
  1. 推荐使用console调试而非alert
alert这种方式既费事(调试完之后还得清理)又麻烦(如果有漏洞的警告框出现在产品环境中,会给用户造成不便)。
所有主流浏览器都有 JavaScript 控制台,该控制台可用于查询 JavaScript 错误。
这些浏览器都支持通过 console 对象直接把 JavaScript 消息写入控制台,这个对象包含如下方法:
    error(message):在控制台中记录错误消息。
    info(message):在控制台中记录信息性内容。
    log(message):在控制台记录常规消息。
    warn(message):在控制台中记录警告消息。
  1. 使用 JavaScript 调试器
    在所有主流浏览器中都可以使用的还有 JavaScript 调试器。ECMAScript 5.1 规范定义了 debugger关键字,用于调用可能存在的调试功能。如果没有相关的功能,这条语句会被简单地跳过。可以像下面这样使用 debugger 关键字:
function pauseExecution(){ 
   console.log("Will print before breakpoint")
   debugger
   console.log("Will not print until breakpoint continues")
}

在运行时碰到这个关键字时,所有主流浏览器都会打开开发者工具面板,并在指定位置显示断点。然后,可以通过单独的浏览器控制台在断点所在的特定词法作用域中执行代码。此外,还可以执行标准的代码调试器操作(单步进入、单步跳过、继续,等等)。
浏览器也支持在开发者工具的源代码标签页中选择希望设置断点的代码行来手动设置断点(不使用debugger 关键字)。这样设置的断点与使用 debugger 关键字设置的一样,只是不会在不同浏览器会话之间保持。

你可能感兴趣的:(JS 错误Error)