抛出自定义错误是解释函数为什么失败的有效方式。在出现已知函数无法正确执行的情况时就应该
抛出错误。换句话说,浏览器会在给定条件下执行该函数时抛出错误。例如,下面的函数会在参数不是
数组时抛出错误:
function process(values){
values.sort();
for (let value of values){
if (value > 100){
return value;
}
}
return -1;
}
如果给这个函数传入字符串,调用sort()函数就会失败。每种浏览器对此都会给出一个模棱两可
的错误消息,如下所示。
IE:属性或方法不存在。
Firefox:values.sort()不是函数。
Safari:值undefined(对表达式values.sort 求值的结果)不是一个对象。
Chrome:对象名没有方法’sort’。
Opera:类型不匹配(通常是在需要对象时使用了非对象值)。
虽然Firefox、Chrome 和Safari 至少给出了导致错误的相关代码,但并没有哪个错误消息特别明确
地指出发生了什么,或者怎么修复。对于上面的一个函数来说,通过这样的错误消息调试还是很容易的。
但是,如果是一个复杂的Web 应用程序,有几千行JavaScript 代码,想要找到错误的原因就会很难。
这时候,使用适当的信息创建自定义错误可以有效提高代码的可维护性。比如下面的例子:
function process(values){
if (!(values instanceof Array)){
throw new Error(“process(): Argument must be an array.”);
}
values.sort();
for (let value of values){
if (value > 100){
return value;
}
}
return -1;
}
在这个重写后的函数中,如果values 参数不是数组就会抛出错误。错误消息包含函数名以及对错
误原因非常清晰的描述。即使在复杂的应用程序中出现这个错误,也可以很容易理解问题所在。
实际编写JavaScript 代码时,应该仔细评估每个函数,以及可能导致它们失败的情形。良好的错误
处理协议可以保证只会发生你自己抛出的错误。
抛出错误与try/catch
一个常见的问题是何时抛出错误,何时使用try/catch 捕获错误。一般来说,错误要在应用程序
架构的底层抛出,在这个层面上,人们对正在进行的流程知之甚少,因此无法真正地处理错误。如果你
在编写一个可能用于很多应用程序的JavaScript 库,或者一个会在应用程序的很多地方用到的实用函数,
那么应该认真考虑抛出带有详细信息的错误。然后捕获和处理错误交给应用程序就行了。
至于抛出错误与捕获错误的区别,可以这样想:应该只在确切知道接下来该做什么的时候捕获错
误。捕获错误的目的是阻止浏览器以其默认方式响应;抛出错误的目的是为错误提供有关其发生原因的
说明。