摘要:抛出错误信息是每个程序员的梦魇,这意味着不断的修改、测试加上老板的责骂。但是本文的作者为大家开辟了一片新视野,本着事物两面性原则,错误信息有的时候也是咱们程序员的好朋友。
以前,我觉得编程语言中最让人不解的部分就是它能够创建错误。当时我对Java语言中的throw关键字的第一反应就是“啊,这也太傻了,为什么我们想要引发一个错误(error)?”我觉得错误是我的敌人,应当避免的,所以创建错误是毫无用处甚至是危险的。我认为在JavaScript中加入这样的关键字是多此一举。但随着我编程经验的丰富,我逐渐变成了throw我的error粉丝。合理的使用它们会让对代码的调试和维护大大简化。
在编程的时候,Error通常出现在不期望的事情发生时。可能是传入函数的参数值不正确,或者是运算符的操作数不合法。为此编程语言定义了一个基本的规则:当上述情况发生时,就产生一个错误来让编程人员对代码进行修复。如果这些错误不被抛出或反馈给你,那么调试程序几乎是不可能的。如果所有的错误都“悄悄地”发生,那么你很难在第一时间发现问题所在,并将其修复。因此Error是开发者的朋友,而不是敌人。
Error的问题所在是它们会在错误的时间和错误的地点发生。更糟的是,默认的错误信息通常晦涩难懂,很难解释哪里出了问题。JavaScirpt的错误信息更是不包含任何有价值的信息,而且还很隐蔽(尤其是在IE里运行时)。想象一下如果能有这样的错误提示出现“因为某件事情发生导致某个函数调用失败”,那么立刻我们的调试任务就变得简单了,这就是throw自己的error的好处。
我们可以把error想象成内嵌的异常类。在代码的某个特定的地点估计异常的发生肯定要比在所有的地方等待异常的发生要简单。这不光在代码编写中,在产品设计中也是一个普遍认同的原则。就像在轿车上设计了挤压区域和框架,以便在受到撞击时会以期望的方式发生变形。因为知道了框架在受到撞击时会如何变形,哪些零件会失效,这样制造商就可以造出保证乘客安全的汽车。我们的代码也可以按照这样的思想编写。
虽然最近几年JavaScript有了很多进步,但是相比于其它语言的开发者,JavaScript开发者仍然只有少得可怜的调试工具。因此在JavaScript中throw error就显得比其它语言更有价值。我们可以用throw关键字来抛出一个对象。我们可以抛出任何类型的对象,不过Error对象是最常用的:
throw new Error("Something bad happened.") |
当我们用这样的方式抛出错误,而这个错误又不被try-catch捕获时,浏览器就会用其通常的方式显示上面的错误信息(Something bad happened)。在IE里会在浏览器的左下角出现一个小图标,当双击图标时会弹出一个带着上面错误提示的对话框;安装有Firebug插件的火狐浏览器会在控制台显示错误信息;Safar和Chrome会在Web Inspector中显示;Opera会在错误控制台显示。一句话,它们会像你没有抛出错误时一样处理。但不同的是它会通过浏览器向你提供具体的信息,而不是一个发生错误的行列号。你可以为错误信息加入任何需要的信息,来帮你成功解决问题。我建议在错误信息中提供发生错误的函数名称以及错误原因。看下面这个函数:
function addClass(element, className){ element.className += " " + className; } |
这个函数的功能是向一个给定的element加入新的CSS class(这在JavaScript中非常普遍)。但如果element是null的时候会发生什么?你会得到一个这样的错误提示“object expected”,很隐晦。然后你需要查看执行堆栈(如果浏览器支持这个功能)来准确定位错误的源头。如果我们抛出一个错误调试就变得简单了:
function addClass(element, className){ if (element != null && typeof element.className == "string"){ element.className += " " + className; } else { throw new Error("addClass(): First arg must be a DOM element."); } } |