try-catch 语句
try-catch 语句用作于处理 JavaScript 中异常的一种方式。
try{
//可能存在错误的代码
}catch(error){
//在发生错误时如何处理
}
try 块中的任何代码发生错误,都会立即退出代码的执行过程,然后紧接着执行 catch 块,此时,catch 块会接受到一个包含错误信息的对象,这个对象中保存着错误信息的 message 属性。当然因浏览器而异,message属性是唯一一个所有浏览器都支持的属性,也有一些根据浏览器本身添加的其他属性,例如 IE 添加了和 message 属性相同的 description 属性,还添加了保存错误信息数量的 number 属性,火狐 添加了**fileName,lineNumber 和 stack(包含栈跟踪信息)**属性,Safari 添加了 line(表示行号)、sourceId(表示内部错误) 和 sourceURL属性。
finally 子句
try-catch 语句中是可选的,但是finally子句一旦使用,则无论如何代码都会执行。不管try块中的代码是否能够正常执行,finally子句都会执行,因报错执行catch块中的语句时,finally子句也会执行。甚至是try-catch 语句中包含return语句,finally子句也会执行。
function f(){
try{
return 1
}catch(error){
return 2
}finally{
return 0
}
}
f()//0
如果提供了 finally语句,则 catch 子句就成了可选的 (catch 和 finally 子句有一个即可)。但在 IE7 中,除非有 catch 子句,否则 finally 子句中的代码永远不会执行,IE8 修复了这个问题。
错误类型
- Error 基类
- EvalError 使用 eval() 函数而发生异常错误,但在实践中浏览器也有可能抛出 TypeError 错误
- TypeError 在 js 中经常遇到,当变量中保存着不存在的类型变量,或者访问不存在的方法时,都会导致报错。本质就是放变量的类型并不符合要求导致报错的。
- RangeError 数值超出相应范围时抛出
- ReferenceError 找不到对象的情况下,会发生 ReferenceError (这种情况会直接导致大家都知道的 “object expected” 浏览器错误),通常在 访问不存在的变量时,就会报错。
var obj = x; // x 变量没有声明过的时候就会导致 ReferenceError
- SyntaxError 当我们把语法错误的 js 字符串传入 eval() 函数时,就会引起报错
eval("a++b") ;// VM2167:1 Uncaught SyntaxError: Unexpected identifier
- URIError 使用 encodeURL() 和 decodeURL() 时,而 URL 格式不正确,就会导致报错。
Error 是基类,其他的错误类型都是继承这个类型的。Error 类型的错误很少见,即便有也是又浏览器抛出。
抛错
和 try-catch 语句相匹配的还有一个throw 操作符,用于随时自定义报错。
需要给 throw 操作符指定一个值,对于这个值是什么类型,则没有要求。
所以下面的这些都是有效的。
throw 1234;
thorw "hello world";
thorw true;
throw (name : "js");
当遇到 throw 操作符时,代码就会立即停止执行,必须当有try-catch语句捕获到被抛出的值时,代码才会继续执行。
通过throw操作符可以真实的模拟浏览器报错,每种错误类型的构造函数都接受一个参数,即实际的错误信息。例如
throw new Error("Something bad happend.");
throw new TypeErro("What type of variable do you take me for?");
...
通过利用原型链还可以通过继承 Error 来创建自定义错误类型,此时需要为新创建的错误类型指定name 和 message 属性。
function fn(message){
this.name = "CustomError";
this.message = message;
CustomError.prototype = new Error();
throw new CustomError("My message");
}
浏览器对待继承自 Error 的自定义错误类型,就像对待其他错误类型一样。
Error 事件
在没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件,error 事件是 Web 浏览器最在支持的事件之一。 在任何 Web 浏览器中,onerror 事件处理程序都不会创建 event 对象,但它可以接受三个参数:错误消息、错误所在的 URL 和行号。多数情况下,只有错误消息有用。指定 onerror 事件,必须使用 DOM0 级,他并没有遵循 DOM2 级事件的标准格式。
window.onerror = function(message,url,line){
alert(message)
}
只要发生错误,无论是不是浏览器的,都会触发 error 事件,并执行这个事件。然后,浏览器默认的机制发挥作用,就像往常一样显示出错误消息。当然也可以阻止浏览器报告错误的默认行为。
window.onerror = function(message,url,line){
alert(message);
return false;
}
通过 return false 这个函数实际上就相当于整个文档的 try-catch语句,可以捕获所有无代码处理的运行时错误。
图像也是支持 error 事件的。只要图像的 src 属性中的 URL 不能返回可以有效的图像格式,就会触发 error 事件。此时的 error 事件遵循 DOM 格式,会返回一个以图像为目标的 event 对象。
var image = new Image();
EventUtil.addHandler(image,"load",function(event){
alert("Image loaded!")
})
EventUtil.addHandler(image,"error",function(event){
alert("Image not loaded!")
})
image.src = "sim.jpg";//指定不存在的图片。
上面这个例子中,当加载图像失败时会弹出一个警告框,需要注意的是,发生 error 事件时,图像下载过程已经结束了,也就是说不能再重新下载了。
记录 Error
可以在服务器端记录log
像数据库或者服务器错误都会定期写入日志,同样的也推荐把 JavaScript 错误写入保存到服务器端错误的地方,并标明是来自前端的错误。
使用 try-catch 语句就应该把相应的错误记录到日志中。
当然也把错误信息通过 console 打印到浏览器的控制台。亦或者在页面的某个空白地方,把信息打印到页面中。
常见的IE错误
操作终止
在 IE8 之前的版本中,存在一个最让人讨厌的调试错误那就是操作终止。在修改尚未加载完成的页面时,就会发生操作终止错误,发生错误时,会出现一个模拟对话框,告诉你“操作终止”,单机 ok 按钮,然后卸载整个页面,显示一张空白页面。
无效字符
当页面中出现无效字符时,IE 就会抛出无效字符错误,无效字符–>就是在 JavaScript 语法中没有定义的的字符。例如代码是从 word 文档中复制到编辑器中的,然后在 IE 中运行,那就有可能出现无效字符,其他浏览器对无效字符反应和 IE 类似,他们会把无效字符解释为未定义的标识符
未找到成员
IE 中为找到成员错误是由垃圾收集例程配合错误导致的。
比如说,在对象被销毁之后,又给该对象进行赋值操作,就会导致未找到成员错误。
这个错误发生最常见的情形是使用 event 对象的时候,在 IE 中 event 对象是 window 对象的属性,event 对象在事件发生时创建的,在最后一个事件处理程序执行完毕后销毁。假设在一个闭包中使用了 event 对象,而该闭包不会立即执行,那么在将来调用并给 event 对象的属性赋值时,就会导致未找到成员错误。
未知运行时错误
当使用 innerHTML 或者是 outerHTML 以下面这种方式指定 HTML 时,就会发生未知运行时错误。
- 把块元素插入到行内元素时
- 访问表示任意部分(、等)的任意属性时
例如: 标签不能包含
在遇到块级元素被插入到不恰当的位置时,别的浏览器会尝试纠正并隐藏错误,但 IE 会较真这一块,法不容情的报错。
语法错误
一般来说,IE 报语法错误,就说明很可能代码中少了一个分号,或者花括号前后不对称。
当然如果是引入了一个外部的 js 文件。这种情况就需要格外注意了。
引入外部 js 文件,而该文件没有返回 js 代码,IE 也会报语法错误,例如,script 标签的 src 属性引入一个 HTML 文件,就会导致语法错误。
系统无法找到指定资源
IE 最有价值的错误消息,在 js 请求某个资源 URL 时,URL 的长度超过了 IE 对 URL 字符限制的 2083 个字符时,就会发生这个错误(其他浏览器对 URL 限制不严格)。IE 对 URL 路径还有一个不能超过 2048 个字符的限制。