<script type="text/javascript"> function CustomError(message) { this.name = "CustomError"; this.message = message; } CustomError.prototype = new Error(); throw new CustomError("My message"); </script>
这样创建的自定义错误与浏览器错误并不同,所以可是很有用的哦O(∩_∩)O~
注意: IE 只有在抛出 Error 对象时才会显示自定义的错误消息!其他错误对象,它只会显示 “exception thrown and not caught”。
2.1 抛出错误的时机应该在已知的、某种特定错误条件下(会导致函数无法正常执行),抛出自定义的错误:
<script type="text/javascript"> function process(values) { if (!(values instanceof Array)) { throw new Error("process():Argument must be an array."); } values.sort(); for (var i = 0, len = values.length; i < len; i++) { if (values[i] > 100) { return values[i]; } } return -1; } process("hi"); </script>
如果给上面的函数传入一个字符串参数,那么 sort() 就会抛错,所以我们在这里加入了带有适当消息的自定义错误。这对于一个有着几千行脚本代码的项目来说,可以显著地提升代码的可维护性O(∩_∩)O~
错误消息时包含了函数名称以及为什么会发生错误的明确描述,是不是很清晰呀O(∩_∩)O~
在开发时,要注意函数可能失败的因素,把这些因素都加上自定义错误吧!良好的错误处理机制是确保代码只发生我们定义的错误。
2.2 抛出错误与使用 try-catch建议在抛出错误时尽量提供详尽的信息,因为我们抛出错误不就是为了在维护时,能够知道错误发生的具体位置和具体原因的吗?
3 错误事件任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件(IE、Firfox 和 chrome 支持)。它接收 3 个参数:错误消息、错误所在的 URL 和行号。一般只有错误消息有用。只能通过 DOM0 级技术来指定 onerror 事件处理程序,如果返回 false,就可以阻止浏览器报告错误的默认行为:
<script type="text/javascript"> window.onerror= function (message,url,line) { console.log(message); return false; } </script>
这个函数其实就是整个文档的 try-catch 语句,它可以捕获所有没有被处理的运行时错误。理想情况下,错误都被包含在 try-catch 语句中,所以不会使用到它。
注意: 不同的浏览器下,这个函数的处理方式不同。在 IE 中,发生了 onerror 事件,代码仍会执行,所有的变量和数据都会保留。但在 Firefox 中,代码会停止执行,而且之前所有的变量和数据都会被销毁!
图像也支持 error 事件。如果图像的 src 属性中的 URL 无法返回被识别的图像格式时,就会触发持 error 事件。这时的 error 事件会返回一个以图像为目标的 event 对象:
<script type="text/javascript"> var image = new Image(); EventUtil.addHandler(image, "load", function (event) { console.log("Image loaded!"); }); EventUtil.addHandler(image, "error", function (event) { console.log("Image not loaded!"); }); image.src = "smilex.gif";//实际并不存在 </script>
注意,如果发生了 error 事件,那么这个图像的下载过程就已经结束咯。
4 常见的错误类型因为 JavaScript 是松散类型的语言,所以错误只会在代码运行期间发生。一般情况下,我们需要重点关注以下三种错误:
① 类型转换错误
② 数据类型错误
③ 通信错误
在使用相等(==)或不相等(!==),或者在 if、for 或 while 中使用了非布尔值时,最常发生类型转换错误。
所以建议使用全等(===)和不全等(!==)来避免类型转换操作。
if 等语句会自动把任何值都转换为布尔值:
function concat(str1, str2, str3){ var result = str1 + str2; if (str3){//不要这样!!! result +=str3; } return result; }
这个函数是想拼接两个或三个字符串,然后返回结果。所以这里的第三个参数是可选的,,所以必须要检查。如果我们在调用这个函数时,只用到前两个参数,这意味着第三个参数因为是未使用过的命名变量,所以被自动赋值给 undefine,而 undefine 在 if 中会被自动转换为 false,这样可以。但是,如果第三个参数传入数值 0,在 if 中会被自动转换为 false,那么就不会被加到 result 中!所以我们要进行检查:
function concat(str1, str2, str3){ var result = str1 + str2; if (typeof str3 == "string"){ result +=str3; } return result; }
4.2 数据类型错误function getQueryString(url){ var pos = url.indexOf("?"); if (pos > -1){ return url.substring(pos + 1); } return ""; }
这个函数打算返回给定 URL 中的查询字符串。但如果传入非字符串类型的参数,就会导致错误。所以要加上类型判断:
function getQueryString(url){ if(typeof url == "string"){ var pos = url.indexOf("?"); if (pos > -1){ return url.substring(pos + 1); } } return ""; }
还有,如果在流控制语句中使用非布尔值也会导致数据类型错误:
function reverseSort(values){ if (values){//非数组值都会报错 values.sort(); values.reverse(); } }
另一种错误是将参数与 null 进行比较,这只能确保参数不是 null 和 undefined,也不建议将参数与 undefined 进行比较。
还有一种错误是,只针对某一特性进行检测:
function reverseSort(values){ if (typeof values.sort == "function"){ values.sort(); values.reverse(); } }
上面的函数,如果传入带有 sort() 方法的对象,就会通过检测,但会在调用 reverse() 方法时报错!所以这里最好是使用 instanceof 来检测:
function reverseSort(values){ if (values instanceof Array){ values.sort(); values.reverse(); } }