JavaScript笔记:错误处理与调试

1、浏览器报告的错误

IE

IE 是唯一一个在浏览器的界面窗体(chrome)中显示 JavaScript 错误信息的浏览器。在发生 JavaScript 错误时,浏览器左下角会出现一个黄色的图标,图标旁边则显示着”Error on page”(页面中有错误)。 假如不是存心去看的话,你很可能不会注意这个图标。双击这个图标,就会看到一个包含错误消息的对话框,其中还包含诸如行号、字符数、错误代码及文件名(其实就是你在查看的页面的 URL)等相关信息。

Firefox

默认情况下,Firefox 在 JavaScript 发生错误时不会通过浏览器界面给出提示。但它会在后台将错误记录到错误控制台中。单击“Tools”(工具)菜单中的“Error Console”(错误控制台)可以显示错误控制台。你会发现,错误控制台中实际上还包含与 JavaScript、CSS 和 HTML 相关的警告和信息,可以通过筛选找到错误。

目前,最流行的 Firefox 插件 Firebug,已经成为开发人员必备的 JavaScript 纠错工具。这个可以从 www.getfirebug.com 下载到的插件,会在 Firefox 状态栏的右下角区域添加一个图标。默认情况下,右下 角区域显示的是一个绿色对勾图标。在有 JavaScript 错误发生时,图标会变成红叉,同时旁边显示错误 的数量。单击这个红叉会打开 Firebug 控制台,其中显示有错误消息、错误所在的代码行(不包含上下 文)、错误所在的 URL 以及行号。

Safari

Windows 和 Mac OS 平台的 Safari 在默认情况下都会隐藏全部 JavaScript 错误。为了访问到这些信息,必须启用“Develop”(开发)菜单。为此,需要单击“Preferences”(偏好设置),然后在“Advanced”(高级)选项卡中,选中“Show develop menu in menubar”(在菜单栏中 显示“开发”菜单)。启用此项设置之后,就会在 Safari 的菜单栏中看到一个“Develop”菜单。

“Develop”菜单中提供了一些与调试有关的选项,还有一些选项可以影响当前加载的页面。单击 “Show Error Console”(显示错误控制台)选项,将会看到一组 JavaScript 及其他错误。控制台中显示着错误消息、错误的 URL 及错误的行号。 单击控制台中的错误消息,就可以打开导致错误的源代码。除了被输出到控制台之外,JavaScript错误不会影响 Safari 窗口的外观。

Opera

Opera 在默认情况下也会隐藏 JavaScript 错误,所有错误都会被记录到错误控制台中。要打开错误 控制台,需要单击“Tools”(工具)菜单,在“Advanced”(高级)子菜单项下面再单击“Error Console”(错误控制台)。与 Firefox 一样,Opera 的错误控制台中也包含了除 JavaScript 错误之外的很多来源(如 HTML、CSS、XML、XSLT 等)的错误和警告信息。要分类查看不同来源的消息,可以使用左下角的下拉选择框。

错误消息中显示着导致错误的 URL 和错误所在的线程。有时候,还会有栈跟踪信息。除了错误控制台中显示的信息之外,没有其他途径可以获得更多信息。也可以让 Opera 一发生错误就弹出错误控制台。为此,要在“Tools”(工具)菜单中单击“Preferences” (首选项),再单击“Advanced”(高级)选项卡,然后从左侧菜单中选择“Content”(内容)。单击“JavaScrip Options”(JavaScript 选项)按钮,显示选项对话框。 在这个选项对话框中,选中“Open console on error”(出错时打开控制台),单击“OK”(确定)按钮。这样,每当发生 JavaScript 错误时,就会弹出错误控制台。另外,还可以针对特定的站点来作此设置,方法是单击“Tools”(工具)、“Quick Preferences”(快速参数)、“Edit Site Preferences”(编辑站点首选项),选择“Scripting”(脚本)选项卡,最后选中“Open console on error”(出错时打开 控制台)。

Chrome

与 Safari 和 Opera 一样,Chrome 在默认情况下也会隐藏 JavaScript 错误。所有错误都将被记录到 Web Inspector 控制台中。要查看错误消息,必须打开 Web Inspector。为此,要单击位于地址栏右侧的 “Control this page”(控制当前页)按钮,选择“Developer”(开发人员)、“JavaScript console”(JavaScript控制台)。

打开的 Web Inspector 中包含着有关页面的信息和 JavaScript 控制台。控制台中显示着错误消息、错误的 URL 和错误的行号。

单击 JavaScript 控制台中的错误,就可以定位到导致错误的源代码行。

2、错误处理

(谆谆教诲ing)
虽然客户端应用程序的错误处理很重要,但真正受到重视,还是最近几年的事。实际上,我们 要面对这样一个不争的事实:使用 Web 的绝大多数人都不是技术高手,其中甚至有很多人根本就不明白浏览器到底是什么,更不用说让他们说喜欢哪一个了。本章前面讨论过,每个浏览器在发生 JavaScript 错误时的行为都或多或少有一些差异。有的会显示小图标,有的则什么动静也没有,浏览器对 JavaScript 错误的这些默认行为对最终用户而言,毫无规律可循。最理想的情况下,用户遇到错误搞不清为什么,他们会再试着重做一次;最糟糕的情况下,用户会恼羞成怒,一去不复返了。良好的错误处理机制可以 让用户及时得到提醒,知道到底发生了什么事,因而不会惊惶失措。为此,作为开发人员,我们必须理解在处理 JavaScript 错误的时候,都有哪些手段和工具可以利用。

try-catch语句

ECMA-262 第 3 版引入了 try-catch 语句,作为 JavaScript 中处理异常的一种标准方式。基本的语法如下所示:

try{
    // 可能会导致错误的代码 
} catch(error){
    // 在错误发生时怎么处理 
}

如果 try 块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行 catch 块。此时,catch 块会接收到一个包含错误信息的对象。与在其他语言中不同的是,即使你不想使用这个错误对象,也要给它起个名字。这个对象中包含的实际信息会因浏览器而异,但共同的是有一个保存着错误消息的 message 属性。ECMA-262 还规定了一个保存错误类型的 name 属性;当前所有浏览器都支持这个属性(Opera 9 之前的版本不支持这个属性)。因此,在发生错误时,就可以像下面这样实事求是地显 示浏览器给出的消息:

try {
    window.someNonexistentFunction();
} catch (error){
    alert(error.message);
}

这个例子在向用户显示错误消息时,使用了错误对象的message属性。这个message属性是唯一 一个能够保证所有浏览器都支持的属性。

finally 子句:

虽然在 try-catch 语句中是可选的,但 finally 子句一经使用,其代码无论如何都会执行。换句话说,try 语句块中的代码全部正常执行,finally 子句会执行;如果因为出错而执行了 catch 语句块,finally 子句照样还会执行。只要代码中包含 finally 子句,则无论 try 或 catch 语句块中包含什么代码——甚至 return 语句,都不会阻止 finally 子句的执行。

function testFinally(){
        try {
            return 2;
        } catch (error){
            return 1;
        } finally {
            return 0; 
        }
}

这个函数在 try-catch 语句的每一部分都放了一条 return 语句。表面上看,调用这个函数会返回 2,因为返回 2 的 return 语句位于 try 语句块中,而执行该语句又不会出错。可是,由于最后还有 一个 finally 子句,结果就会导致该 return 语句被忽略;也就是说,调用这个函数只能返回 0。如果把 finally 子句拿掉,这个函数将返回 2。

错误类型:

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

其中,Error 是基类型,其他错误类型都继承自该类型。因此,所有错误类型共享了一组相同的属性(错误对象中的方法全是默认的对象方法)。Error 类型的错误很少见,如果有也是浏览器抛出的;这个基类型的主要目的是供开发人员抛出自定义错误。

EvalError 类型的错误会在使用eval()函数而发生异常时被抛出。
(注:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。)
ECMA-262 中对这个错误有如下描述:如果以非直接调用的方式使用 eval 属性的值(换句话说,没有明确地将其名称作为一个 Identifier,即用作 CallExpression 中的 MemberExpression),或者为 eval 属性赋值。简单 地说,如果没有把 eval()当成函数调用,就会抛出错误,例如:

new eval();
eval = foo;
//均会抛出EvalError

RangeError 类型的错误会在数值超出相应范围时触发。例如,在定义数组时,如果指定了数组不支持的项数(如20或 Number.MAX_VALUE),就会触发这种错误:

var items1 = new Array(-20); //抛出RangeError 
var items2 = new Array(Number.MAX_VALUE); //抛出RangeError

在找不到对象的情况下,会发生 ReferenceError(这种情况下,会直接导致人所共知的”object expected”浏览器错误)。通常,在访问不存在的变量时,就会发生这种错误,例如:

var obj = x; //在 x 并未声明的情况下抛出 ReferenceError

至于 SyntaxError,当我们把语法错误的 JavaScript 字符串传入 eval()函数时,就会导致此类错误。例如:

eval("a ++ b"); //抛出SyntaxError

TypeError 类型在 JavaScript 中会经常用到,在变量中保存着意外的类型时,或者在访问不存在的方法时,都会导致这种错误。错误的原因虽然多种多样,但归根结底还是由于在执行特定于类型的操作时,变量的类型并不符合要求所致。下面来看几个例子:

var o = new 10; //抛出TypeError 
alert("name" in true); //抛出TypeError 
Function.prototype.toString.call("name"); //抛出 TypeError

最常发生类型错误的情况,就是传递给函数的参数事先未经检查,结果传入类型与预期类型不相符。

在使用 encodeURI()或 decodeURI(),而 URI 格式不正确时,就会导致 URIError 错误。

利用不同的错误类型,可以获悉更多有关异常的信息,从而有助于对错误作出恰当的处理。要想知道错误的类型,可以像下面这样在 try-catch 语句的 catch 语句中使用 instanceof 操作符:

try {
    someFunction();
} catch (error){
    if (error instanceof TypeError){ 
        //处理类型错误
    } else if (error instanceof ReferenceError){ 
        //处理引用错误
    } else { 
        //处理其他类型的错误
    }
}

使用 try-catch 最适合处理那些我们无法控制的错误。假设你在使用一个大型 JavaScript 库中的函数,该函数可能会有意无意地抛出一些错误。由于我们不能修改这个库的源代码,所以大可将对该函数的调用放在 try-catch 语句当中,万一有什么错误发生,也好恰当地处理它们。

抛出错误

与 try-catch 语句相配的还有一个 throw 操作符,用于随时抛出自定义错误。抛出错误时,必须要给 throw 操作符指定一个值,这个值是什么类型,没有要求。下列代码都是有效的:

throw 12345;
throw "Hello world!";
throw true;
throw { name: "JavaScript"};

在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代码才会继续执行。
通过使用某种内置错误类型,可以更真实地模拟浏览器错误。每种错误类型的构造函数接收一个参数,即实际的错误消息。下面是一个例子:

throw new Error("Something bad happened.");

像下面使用其他错误类型,也可以模拟出类似的浏览器错误:

throw new SyntaxError("I don’t like your syntax.");
throw new TypeError("What type of variable do you take me for?"); throw new RangeError("Sorry, you just don’t have the range.");
throw new EvalError("That doesn’t evaluate.");
throw new URIError("Uri, is that you?");
throw new ReferenceError("You didn’t cite your references properly.");

另外,利用原型链还可以通过继承 Error 来创建自定义错误类型,此时,需要为新创建的错误类型指定 name 和 message 属性。

function CustomError(message){
    this.name = "CustomError";
    this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("My message");

浏览器对待继承自 Error 的自定义错误类型,就像对待其他错误类型一样。如果要捕获自己抛出的错误并且把它与浏览器错误区别对待的话,创建自定义错误是很有用的。

抛出错误的时机:

要针对函数为什么会执行失败给出更多信息,抛出自定义错误是一种很方便的方式。应该在出现某 种特定的已知错误条件,导致函数无法正常执行时抛出错误。换句话说,浏览器会在某种特定的条件下执行函数时抛出错误。例如,下面的函数会在参数不是数组的情况下失败:

function process(values){
    values.sort();
    for (var i=0, len=values.length; i < len; i++){
        if (values[i] > 100){
            return values[i];
        }
    }
    return -1; 
}

如果执行这个函数时传给它一个字符串参数,那么对 sort()的调用就会失败。对此,不同浏览器会给出不同的错误消息,但都不是特别明确。这种情况下,带有适当信息的自定义错误能够显著提升代码的可维护性。 来看下面的例子。

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; 
}

在重写后的这个函数中,如果 values 参数不是数组,就会抛出一个错误。错误消息中包含了函数的名称,以及为什么会发生错误的明确描述。如果一个复杂的 Web 应用程序发生了这个错误,那么查找问题的根源也就容易多了。
建议读者在开发 JavaScript 代码的过程中,重点关注函数和可能导致函数执行失败的因素。良好的错误处理机制应该可以确保代码中只发生你自己抛出的错误。

错误事件

任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件。
在任何 Web 浏览器中,onerror 事件处理程序都不会创建 event 对象,但它可以接收三个参数:错误消息、错误所在的 URL 和行号。

window.onerror = function(message, url, line){
    alert(message);
};

只要发生错误,无论是不是浏览器生成的,都会触发 error 事件,并执行这个事件处理程序。然后,浏览器默认的机制发挥作用,像往常一样显示出错误消息。像下面这样在事件处理程序中返回 false,可以阻止浏览器报告错误的默认行为:

window.onerror = function(message, url, line){
    alert(message);
    return false;
};

通过返回 false,这个函数实际上就充当了整个文档中的 try-catch 语句,可以捕获所有无代码处理的运行时错误。这个事件处理程序是避免浏览器报告错误的最后一道防线,理想情况下,只要可能就不应该使用它。只要能够适当地使用 try-catch 语句,就不会有错误交给浏览器,也就不会触发 error 事件。

图像也支持 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 = "smilex.gif"; //指定不存在的文件

在这个例子中,当加载图像失败时就会显示一个警告框。需要注意的是,发生 error 事件时,图像下载过程已经结束,也就是说不能再重新下载了。

处理错误的策略

在 Web 应用程序的 JavaScript 这一端,错误处理策略同服务器端一样重要。由于任何 JavaScript 错误都可能导致网页无法使用,因此搞清楚何时以及为什么发生错误至关重要。
绝大多数 Web 应用程序的用户都不懂技术,遇到错误时很容易心烦意乱。有时候,他们可能会刷新页面以期解决问题,而有时候则会放弃努力。作为开发人员,必须要知道代码何时可能出错,会出什么错,同时还要有一个跟踪此类问题的系统。

常见的错误类型

一般来说,需要关注三种错误:
类型转换错误
数据类型错误
通信错误

类型转换错误:

类型转换错误发生在使用某个操作符,或者使用其他可能会自动转换值的数据类型的语言结构时。
在使用相等(==)和不相等(!=)操作符,或者在 if、for 及 while 等流控制语句中使用非布尔值时, 最常发生类型转换错误。

相等和不相等操作符在执行比较之前会先转换不同类型的值。由于在非动态语言中, 开发人员都使用相同的符号执行直观的比较,因此在 JavaScript 中往往也会以相同方式错误地使用它们。 多数情况下,我们建议使用全等(===)和不全等(!==)操作符,以避免类型转换。

alert(5 == "5");//true
alert(5 === "5");//false
alert(1 == true);//true
alert(1 === true);//false

这里使用了相等和全等操作符比较了数值5和字符串”5”。相等操作符首先会将数值5转换成字符 串”5”,然后再将其与另一个字符串”5”进行比较,结果是 true。全等操作符知道要比较的是两种不同的数据类型,因而直接返回 false。对于 1 和 true 也是如此:相等操作符认为它们相等,而全等操作 符认为它们不相等。使用全等和非全等操作符,可以避免发生因为使用相等和不相等操作符引发的类型转换错误,因此我们强烈推荐使用。

容易发生类型转换错误的另一个地方,就是流控制语句。像 if 之类的语句在确定下一步操作之前,会自动把任何值转换成布尔值。尤其是 if 语句,如果使用不当,最容易出错。来看下面的例子:

function concat(str1, str2, str3){
    var result = str1 + str2;
    if (str3){ //绝对不要这样!!!
          result += str3;
    }
    return result;
}

// 修改
function concat(str1, str2, str3){ 
    var result = str1 + str2;
    if (typeof str3 == "string"){//恰当的比较
        result += str3;
    }
    return result;
}

在这个重写后的函数中,if 语句的条件会基于比较返回一个布尔值。这个函数相对可靠得多,不 容易受非正常值的影响。

数据类型错误:

JavaScript 是松散类型的,也就是说,在使用变量和函数参数之前,不会对它们进行比较以确保它们的数据类型正确。为了保证不会发生数据类型错误,只能依靠开发人员编写适当的数据类型检测代码。 在将预料之外的值传递给函数的情况下,最容易发生数据类型错误。

//不安全的函数,任何非字符串值都会导致错误:indexOf和substring函数只能操作字符串,因此只要传入其他数据类型的值就会导致错误。
function getQueryString(url){
    var pos = url.indexOf("?");
    if (pos > -1){
        return url.substring(pos +1);
    }
    return ""; 
}

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();
     }
}
//安全,非数组值将被忽略 
function reverseSort(values){
    if (values instanceof Array){
        values.sort();
        values.reverse();
    } 
}

大体上来说,基本类型的值应该使用 typeof 来检测,而对象的值则应该使用 instanceof 来检测。

根据使用函数的方式,有时候并不需要逐个检测所有参数的数据类型。但是,面向公众的 API 则必须无条件地执行类型检查,以确保函数始终能够正常地执行。

通信错误:

随着 Ajax 编程的兴起,Web 应用程序在其生命周期内动态加载信息或功能, 已经成为一件司空见惯的事。不过,JavaScript 与服务器之间的任何一次通信,都有可能会产生错误。

第一种通信错误与格式不正确的 URL 或发送的数据有关。
最常见的问题是在将数据发送给服务器之前,没有使用 encodeURIComponent()对数据进行编码。例如,下面这个 URL 的格式就是不正确的:
http://www.yourdomain.com/?redir=http://www.someotherdomain.com?a=b&c=d

针对”redir=”后面的所有字符串调用 encodeURIComponent()就可以解决这个问题。得到:
http://www.yourdomain.com/?redir=http%3A%2F%2Fwww.someotherdomain.com%3Fa%3Db%26c%3Dd

对于查询字符串,应该记住必须要使用 encodeURIComponent()方法。为了确保这一点,有时候可以定义一个处理查询字符串的函数,例如:

function addQueryStringArg(url, name, value){
    if (url.indexOf("?") == -1){
        url += "?";
    } else {
        url += "&"; 
    }
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url; 
}

var url = "http://www.somedomain.com";
var newUrl = addQueryStringArg(url, "redir", "http://www.someotherdomain.com?a=b&c=d");
alert(newUrl);

另外,在服务器响应的数据不正确时,也会发生通信错误。在没有返回相应资源的情况下,Firefox、 Chrome 和 Safari 会默默地失败,IE 和 Opera 则都会报错。在某些情况下,使用 Ajax 通信可以提供有关错误状态的更多信息。

区分致命错误和非致命错误

把错误记录到服务器

开发 Web 应用程序过程中的一种常见的做法,就是集中保存错误日志,以便查找重要错误的原因。

例如数据库和服务器错误都会定期写入日志,而且会按照常用 API 进行分类。在复杂的 Web 应用程序中,我们同样推荐你把 JavaScript 错误也回写到服务器。换句话说,也要将这些错误写入到保存服务器端错误的地方,只不过要标明它们来自前端。把前后端的错误集中起来,能够极大地方便对数据的分析。

要建立这样一种 JavaScript 错误记录系统,首先需要在服务器上创建一个页面(或者一个服务器入口点),用于处理错误数据。这个页面的作用无非就是从查询字符串中取得数据,然后再将数据写入错误日志中。

这个页面可能会使用如下所示的函数:

function logError(sev, msg){
    var img = new Image();
    img.src = "log.php?sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent(msg);
}

这个 logError()函数接收两个参数:表示严重程度的数值或字符串(视所用系统而异)及错误消息。其中,使用了 Image 对象来发送请求,这样做非常灵活,主要表现如下几方面。
所有浏览器都支持 Image 对象,包括那些不支持 XMLHttpRequest 对象的浏览器。
可以避免跨域限制。通常都是一台服务器要负责处理多台服务器的错误,而这种情况下使用XMLHttpRequest 是不行的。
在记录错误的过程中出问题的概率比较低。大多数 Ajax 通信都是由 JavaScript 库提供的包装函数来处理的,如果库代码本身有问题,而你还在依赖该库记录错误,可想而知,错误消息是不可能得到记录的。

只要是使用 try-catch 语句,就应该把相应错误记录到日志中。来看下面的例子。

for (var i=0, len=mods.length; i < len; i++){
    try {
        mods[i].init();
    } catch (ex){
        logError("nonfatal", "Module init failed: " + ex.message);
    } 
}

在这里,一旦模块初始化失败,就会调用 logError()。第一个参数是”nonfatal”(非致命),表 示错误的严重程度。第二个参数是上下文信息加上真正的 JavaScript 错误消息。记录到服务器中的错误消息应该尽可能多地带有上下文信息,以便鉴别导致错误的真正原因。

3、调试技术

将消息记录到控制台

IE8、Firefox、Opera、Chrome 和 Safari 都有 JavaScript 控制台,可以用来查看 JavaScript 错误。而且,在这些浏览器中,都可以通过代码向控制台输出消息。

可以通过 console 对象向 JavaScript 控制台中写入消息,这个对象具有下列方法:
error(message):将错误消息记录到控制台
info(message):将信息性消息记录到控制台
log(message):将一般消息记录到控制台
warn(message):将警告消息记录到控制台

Opera 10.5 之前的版本中,JavaScript 控制台可以通过 opera.postError()方法来访问。这个方法接受一个参数,即要写入到控制台中的参数,其用法如下:

opera.postError("message");

还有一种方案是使用 LiveConnect,也就是在 JavaScript 中运行 Java 代码。Firefox、Safari 和 Opera 12 都支持 LiveConnect,因此可以操作 Java 控制台。例如,通过下列代码就可以在 JavaScript 中把消息写入到 Java 控制台:

java.lang.System.out.println("Your message");

不存在一种跨浏览器向 JavaScript 控制台写入消息的机制,但下面的函数倒可以作为统一的接口。

function log(message){
    if (typeof console == "object"){
        console.log(message);
    } else if (typeof opera == "object"){
        opera.postError(message);
    } else if (typeof java == "object" && typeof java.lang == "object"){
        java.lang.System.out.println(message);
    }
}

将消息记录到当前页面

另一种输出调试消息的方式,就是在页面中开辟一小块区域,用以显示消息。这个区域通常是一个 元素,而该元素可以总是出现在页面中,但仅用于调试目的;也可以是一个根据需要动态创建的元素。

这种方式下,页面中会有一小块区域显示错误消息。这种技术在不支持 JavaScript 控制台的 IE7 及更早版本或其他浏览器中十分有用。

抛出错误

如前所述,抛出错误也是一种调试代码的好办法。如果错误消息很具体,基本上就可以把它当作确 定错误来源的依据。
对于大型应用程序来说,自定义的错误通常都使用 assert()函数抛出。这个函数接受两个参数, 一个是求值结果应该为 true 的条件,另一个是条件为 false 时要抛出的错误。以下就是一个非常基本 的 assert()函数:

function assert(condition, message){
    if (!condition){
        throw new Error(message);
    }
}

可以用这个 assert()函数代替某些函数中需要调试的 if 语句,以便输出错误消息。下面是使用这个函数的例子:

function divide(num1, num2){
    assert(typeof num1 == "number" && typeof num2 == "number", "divide(): Both arguments must be numbers.");
    return num1 / num2;
}

可见,使用 assert()函数可以减少抛出错误所需的代码量,而且也比前面的代码更容易看懂。

4、常见的IE错误

操作终止
无效字符
未找到成员
未知运行时错误
语法错误
系统无法找到指定资源

你可能感兴趣的:(JavaScript)