javascript基础学习系列三百五十三:抛出错误

如前所述,抛出错误是调试代码的很好方式。如果错误消息足够具体,只要看一眼错误就可以确定 原因。好的错误消息包含关于错误原因的确切信息,因此可以减少额外调试的工作量。比如下面的函数:

 function divide(num1, num2) {
  return num1 / num2;
}

旧版 IE 的常见错误

这个简单的函数执行两个数的除法,但如果任何一个参数不是数值,则返回 NaN。当 Web 应用程序 意外返回 NaN 时,简单的计算可能就会出问题。此时,可以检查每个参数的类型是不是数值,然后再进 16 行计算。来看下面的例子:

function divide(num1, num2) {
  if (typeof num1 != "number" || typeof num2 != "number"){
    throw new Error("divide(): Both arguments must be numbers.");
}
  return num1 / num2;
}

这里,任何一个参数不是数值都会抛出错误。错误消息中包含函数名和错误的具体原因。当浏览器 报告这个错误消息时,你立即就能根据它包含的信息定位到问题,包括问题的解决方案。相对于没那么 具体的浏览器错误消息,这个错误消息显示更有价值。
在大型应用程序中,自定义错误通常使用 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()函数可以减少抛出自定义错误所需的代码量,并且让代码更好 理解。

旧版IE的常见错误

IE 曾是最难调试 JavaScript 错误的浏览器之一。该浏览器的旧版本抛出的错误通常比较短,比较含 糊,缺少上下文。接下来几节分别讨论旧版 IE 中可能会出现的常见且难于调试的 JavaScript 错误。因为 这些浏览器不支持 ES6,所以代码会考虑向后兼容。

无效字符

JavaScript 文件中的代码必须由特定字符构成。在检测到 JavaScript 文件中存在无效字符时,IE 会抛 出"invalid character"错误。所谓无效字符,指的是 JavaScript 语法中没有定义过的字符。例如, 27 一个看起来像减号而实际上并不是减号的字符(Unicode 值为\u2013)。这个字符不能用于代替减号
(ASCII 码为 45),因为它不是 JavaScript 语法定义的减号。这个特殊字符经常会被自动插入 Word 文档, 因此如果把它从 Word 文档复制到文本编辑器然后在 IE 中运行,IE 就会报告文件中包含非法字符。其他

错误处理与调试

浏览器也类似,Firefox 抛出"illegal character"错误,Safari 报告语法错误,而 Opera 则报告
ReferenceError(因为把这个字符当成了未定义标识符来解释)。

未找到成员

如前所述,旧版 IE 中所有 DOM 对象都是用 COM 对象实现的,并非原生 JavaScript 对象。在涉及 垃圾回收时,这可能会导致很多奇怪的行为。其中,"member not found"错误是 IE 中垃圾回收程序 常报告的错误。
这个错误通常会在给一个已被销毁的对象赋值时发生。这个对象必须是 COM 对象才会出现这个消 息。最好的一个例子就是 event 对象。IE 的 event 对象是作为 window 的一个属性存在的,会在事件 发生时创建,在事件处理程序执行完毕后销毁。因此,如果你想在稍后会执行的闭包中使用 event 对 象,尝试给 event 对象赋值就会导致这个错误,如下面的例子所示:

document.onclick = function() {
      var event = window.event;
      setTimeout(function(){
event.returnValue = false; // 未找到成员 }, 1000);
};

在这个例子中,文档被添加了单击事件处理程序。事件处理程序把 window.event 对象保存在一 个名为 event 的本地变量中。然后,在传递给 setTimeout()的闭包中引用这个事件变量。当 onclick 事件处理程序退出后,event 对象会被销毁,因此闭包中对它的引用也就不存在了,于是就会报告未找 到成员错误。之所以给 event.returnValue 赋值会导致"member not found"错误,是因为不能给 已将其成员销毁的 COM 对象赋值。

未知运行时错误

使用 innerHTML 或 outerHTML 属性以下面一种方式添加 HTML 时会发生未知运行时错误:比如将 块级元素插入行内元素,或者在表格的任何部分(table、tbody等)访问了其中一个属性。例如, 从技术角度来说,p标签不能包含另一个块级元素,如div,因此以下代码会导致未知运行时错误:

   p.innerHTML = "<div>Hi</div>"; // where p contains a <p> element

在将块级元素插入不恰当的位置时,其他浏览器会尝试纠正,这样就不会发生错误,但 IE 在这种 情况下要严格得多。

  • 19
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值