《JavaScript 高级程序设计》 第二十一章 错误处理与调试 学习记录

307 阅读4分钟

1、浏览器错误报告

1、桌面控制台 console

2、移动控制台

2、错误处理

1、try/catch 语句

try {
  // 可能出错的代码
}catch(error) {
  // 出错时要怎么做
  console.log(error.message)
}

1、finally语句

  • 始终执行,即使return也无法阻止。
function testFinally() {
  try{
    return 2
  }catch(error) {
    return 1
  }finally {
    return 0
  }
}
testFinally() // 0

2、错误类型

  • Error

    • 基类型,其他错误类型继承该类型,主要用于抛出自定义错误
  • InternalError

    • 在底层JavaScript引擎抛出异常时由浏览器抛出,如栈溢出。
  • EvalError

    • 在使用eval()函数时发生异常时抛出
  • RangeError

    • 数值越界时抛出,如定义数组设置了不支持的长度。
  • ReferenceError

    • 会在找不到对象时触发,如访问不存在的变量而导致的。
  • SyntaxError

    • eval()传入的字符串包含JavaScript语法错误时发生
  • TypeError

    • 变量不是预期类型,或者访问不存在的方法
  • URIError

    • 在使用encodeURI()decodeURI()但传入的格式错误时才会抛出
  • 可以在catch块中,使用instanceof操作符确定错误类型。

3、try/catch 的用法

  • 可以针对特定错误类型实现自定义的错误处理
  • 最好用在自己无法控制的错误上。如使用了大型JavaScript库的某个函数。
  • 如果明确知道代码会发生某种错误,就不适合使用try/catch语句

2、抛出错误

  • throw操作符使用时,代码立即停止,除try/catch捕获了抛出的值
  • 可以通过内置的错误类型来模拟浏览器错误。每种错误类型都只接收一个参数,即错误消息。
  • 自定义错误常用的错误类型是Error、RangeError、ReferenceError和TypeError
  • 通过继承Error,可以创建自定义的错误类型,需要提供name属性和message属性

1、何时抛出错误

  • 使用适当的信息创建自定义错误可以有效提高代码的可维护性。

2、抛出错误与try/catch

  • 错误只要在应用程序架构的底层抛出,在这个层面上无法真正地处理错误。
  • 捕获错误的目的是阻止浏览器以其默认方式响应
  • 抛出错误目的是为错误提供有关其发生原因的说明

3、error事件

  • 任何没有被try/catch语句处理的错误都会在window对象上触发error事件。
  • error事件处理程序中,不会传入event对象,而会传入三个参数:错误信息、发生错误的URL和行号。
window.addEventListener('error', (message, url, line)=> {
  //...
  return false
})
  • 返回false可以阻止浏览器默认报告错误的行为。

  • 图片也支持error事件。任何时候,如果图片src属性中的URL没有返回可是别的图片格式,就会触发error事件。

4、错误处理策略

  • 日志记录、监控系统

5、识别错误

  • 首先识别错误可能会在代码中的什么地方发生。
    • 类型转换错误
    • 数据类型错误
    • 通信错误

1、静态代码分析器

  • 通过在代码构建流程中添加静态代码分析或代码检查器,可以预先发现非常多错误。常见检查器JSHint、JSLint、Google Closure 和 TypeScript

2、类型转换错误

  • 主要原因是使用了会自动改变某个值的数据类型的操作符或语言构造。
  • 使用等于不等于操作符,以及在if、for或while等流控制语句中使用非布尔值。
  • 类型转换错误也会发生在流控制语句中,应当使用typeof判断。

3、数据类型错误

function reverseSort(values) {
  // if(value){ 错误
  // if(value != null){ 错误
  // if(typeof values.sort === 'function'){ 错误
  if(values instanceof Array){
    values.sort()
    values.reverse()
  }
}

4、通信错误

  • URL格式或发送数据的格式不正确。(没有encodeURIComponent() )
  • 服务器响应非预期值时也会发生通信错误。
    • 请求资源不可用
    • 没有返回预期资源。

6、区分重大与非重大错误

  • 非重大
    • 不会影响用户主要任务
    • 只影响页面某个部分
    • 可以恢复
    • 重复操作可能成功
  • 重大
    • 应用程序绝对无法继续运行
    • 严重影响了用户的主要目标
    • 会导致其他错误

7、把错误记录到服务器中

  • 日志存储和跟踪系统
  • logError()
function logError(sev, msg) {
  let img = new Image()
  let encodedSev = encodeURIComponent(sev)
  let encodedMeg = encodeURIComponent(msg)
  img.src = `xxx.log?sev=${encodedSev}&msg=${encodedMeg}`
}

3、调试技术

1、记录在控制台

  • console

2、理解控制台运行时

3、使用JavaScript调试器

  • debugger关键字,等同断点

4、在页面打印消息

5、补充控制台方法

  • 可以重定义console.log()

6、抛出错误

4、旧版IE常见错误

1、无效字符 invaild character

2、未找到成员 xxx not found

3、未知运行错误

4、语法错误

5、系统找不到指定资源

  • URL长度超过2083