JavaScript异常处理机制

917 阅读5分钟

异常仅用于无法预期的问题,读取一个文件时文件不存在不应该是异常

总体来看JavaScript中有三种类型的错误

  • Load time errors加载时间错误,并且会动态生成错误。发生于加载网页时,例如出现语法错误等状况
  • Run time errors由于在HTML语言中滥用命令而导致的错误
  • Logical Errors

浏览器的程序错误

与直接运行在OS上的应用程序不同(例如Node应用程序),在浏览器中运行的,JavaScript程序不会真正的崩溃。如果JavaScript程序运行期间出现异常,且代码中没有catch语句处理它,开发者控制台将会显示一条错误消息,然后一切照旧。

window.onerror会在控制台打印输出错误消息之前被调用,接收到三个参数:

  1. 描述错误的消息
  2. 字符串-导致错误的代码的url
  3. 文档中发生错误所在的代码的行号 你可以在window.onerror处理错误并返回true来阻止打印

类似的promise被拒绝但是没有处理-window.onunhandledrejection

错误类型

  1. Error基类型
  2. InternalError底层js引擎抛出,栈溢出。代码错误或者危险
  3. EvalError调用eval()异常
  4. RangeError 数值越界
  5. ReferenceError找不到对象
  6. SyntaxError
  7. TypeError
  8. URIError 错误的URL格式

throw操作符可以抛出一个异常 同一情况, 每个浏览器给出的错误消息可能不同,所以我们可以自定义抛出错误的类型

try、catch处理异常

try{
	可能会出错的代码;
}catch(error){
	console.log(error.message);
	出错处理;
}finally{
	//finally可以没有
	忽略上面的所有return, 一定会被执行的代码;

}

error事件 没有被try/catch语句处理的错误都会在Window对象上触发error事件 try-catch 语句,作为 JavaScript 中处理异常的一种标准方式。基本的语法如下所示:

如果 try 块中的任何代码发生了错误,就会立即退出代码执行过程,去执行 最近的异常处理程序即catch 块。

如果发生异常的代码没有关联的catch子句,解释器会检查上一层的代码块,查看是否有关联的异常处理程序。如果一直没有找到,就将异常作为错误报告给用户

此时,catch 块会接收到一个包含错误信息的对象。对象中包含一个保存着错误消息的 message 属性和一个保存错误类型的 name 属性。

虽然ECMAScript没有规定,但是Node和所有现代浏览器都实现了Error对象上的stack属性: 多行字符串,创建错误对象时JavaScript调用栈的栈跟踪信息,部分运行环境(node、浏览器)实现了error.stack属性 在这里插入图片描述

finally 子句 在 try-catch 语句中是可选的,但 finally 子句一经使用,其代码无论如何都会执行。

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

只要代码中包含 finally 子句,那么无论try 还是catch 语句块中的return 语句都将被忽略。 如果提供 finally 子句,则 catch 子句就成了可选的(catch 或 finally 有一个即可)。

安全性

通过限制函数的可操作对象,只让函数操作他们需要用到的引用,就可以在一定程度是那个限制函数潜在的破坏力。然而在实践中,异常可能为两个函数提供了沟通渠道,例如:

服务器上有两个包A、B,这样做法潜在风险,但是两个包各有用处。假设给A访问网络套接字的权限,给B访问服务器私钥的权限,A、B无法通信,那么就很完美地规避了风险。 但是在一些场景下,A需要通过B访问私钥。我们不想让其与B直接接触,就编写了一个受信的中间函数来调用B。

这时候就隔绝了A、B,但是如果B throw error,中间函数没有catch或者是再次throw error,A就会获得error。

自定义error类型

class HTTPError extends Error{
    constructor(status,statusText,url){
        super(`${status} ${statusText}:${url}`);
        this.status=status;
        this.statusText=statusText;
        this.url=url;
    }
    get name(){
        return "HTTPError";
    }
}

识别错误

静态代码分析器

通过在代码建构过程中添加静态代码分析器/代码检查器,可以预先发现非常多的错误。这样的分析工具有很多,各自语言都有支持其的分析器。 Github Gist网站

静态代码分析提高代码库的可读性和一致性,同时发现可能的错误和反模式,帮助我们验证现代开发标准并评估其质量。 DeepSource是最受欢迎的静态分析工具之一,可在JavaScript代码库中跟踪800多个潜在问题,例如未使用的变量,空函数,脚本URL的使用等。严格执行ESLint核心JavaScript规则,使我们能够识别错误,反模式和性能不佳的代码。 DeepSource JavaScript分析器当前支持各种Javascript库和框架,例如ReactJS,VueJS,AngularJS,Angular,Ember等,以及各种ECMAScript版本和Typescript。 如果您遵循样式指南,则DeepSource以及模块系统也提供对此的支持。

ESLint也是一个JavaScript代码静态检查工具

调试

console.count
console.dir
console.time
console.timeEnd
console.profileconsole.profileEnd
console.table
monitor(function)
unmonitor(function)