慎用try catch

68次阅读

共计 2821 个字符,预计需要花费 8 分钟才能阅读完成。

前言
自从 ECMA-262 第 3 版引入了 try catch 语句,作为 JavaScript 中处理异常的一种标准方式。基本的语法如下所示。
一、try catch 基本语法
try {
// 可能会导致错误的代码
} catch (error) {
// 在错误发生时怎么处理
}finally {
// 即使报错始终执行
}
二、try catch 特点
1.try catch 耗性能
1.1 try catch 耗性能原理
ECMAScript 2015 -The try Statement
13.15.5 Static Semantics: VarDeclaredNames

TryStatement : try Block Catch Finally
1.Let names be VarDeclaredNames of Block.
2.Append to names the elements of the VarDeclaredNames of Catch.
3.Append to names the elements of the VarDeclaredNames of Finally.
4.Return names.

13.15.6 Static Semantics: VarScopedDeclarations

TryStatement : try Block Catch Finally
1.Let declarations be VarScopedDeclarations of Block.
2.Append to declarations the elements of the VarScopedDeclarations of Catch.
3.Append to declarations the elements of the VarScopedDeclarations of Finally.
4.Return declarations.

根据上面 ECMAScript 文档的 13.15.5 和 13.15.6`。
下面仅为本妹子自己的翻译理解,仅供参考
上面大概说运行 try catch 时,需要将当前的词法环境和作用域全部分别添加到 catch 和 Finally 所要执行的代码块中。从上可以推断出 try catch 是消耗性能的。
1.2 try catch 耗性能实验

下面我用 Chrome62 和 IE9 分别添加多个 try catch, 进行对比实验,虽然,很想抛弃万恶的 IE,但是很多国内的产品不答应呀,除非我们去健身房再多练练,打一架,嘿嘿~~1.2.1 实验数据:
// 没有加 try catch
(function () {
var i = 0;
i++;
}())
// 有 try catch
(function () {
var i = 0;
try {
i++;
} catch (ex) {
} finally {
}
}())
1.2.2 实验结果:

1.2.3 实验链接:
https://jsperf.com/test-try-catch3
https://jsperf.com/test-try-catch
上面实验数据对比得知,try catch 会消耗性能,但是 try catch 对 Chrome 的影响比 IE11 小很多, 据说是 V8 引擎新的编译器 TurboFan 起到的作用,有兴趣的小伙伴们可以看下 v8_8h_source 的 3354 行起,但是 IE11 是 slower 不少的。这就根据小伙伴们的业务对象了,如果只面向现代浏览器,try catch 消耗性能影响会很小;如果需要兼容 IE 或内嵌在低端的 webView 时,可适当考虑下 try catch 消耗性能。
2.try catch 捕获不到异步错误
尝试对异步方法进行 try catch 操作只能捕获当次事件循环内的异常,对 callback 执行时抛出的异常将无能为力。
try {
setTimeout(()=>{
const A = 1
A = 2
},0)
} catch (err) {
// 这里并不能捕获回调里面抛出的异常
console.log(“—–catch error——“)
console.log(err)
}
异步情况想捕获异常,建议在异步函数里包一层 try catch。

setTimeout(() => {
try {
const A = 1
A = 2
} catch (err) {
console.log(err)
}
}, 0)

3.try catch 抛出错误
与 try-catch 语句相配的还有一个 throw 操作符,随时抛出自定义错误,可以根据不同错误类型,创建自定义错误消息。
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.”);
如果觉得自定义的报错不合理,想看原生报错,可以使用 Chrome 的 Pause on exceptions 功能
三、慎用 try catch
try catch 最适合处理那些我们无法控制的错误,如 I / O 操作等,后端 nodeJs 或 java 读取 I / O 操作比较多比如读数据库,所以用 try catch 比较多。前端可以用在上传图片、使用别人的 js 库报错、async await 同步调接口等地方适用。
async function f() {
try {
await Promise.reject(‘ 出错了 ’);
} catch(e) {
}
return await Promise.resolve(‘hello world’);
}
但是大部分前端客户端代码处理都不怎么依赖环境也没有 I / O 操作,都是自己写的代码,在明明白白地知道自己的代码会发生错误时,再使用 try catch 语句就不太合适了,对应数据类型的错误,建议小伙伴们用解构赋值指定默认值、&& 和 || 来规避,所以慎用 try catch。
foo = (obj = {}) => {
let obj1 = result || {};
if (obj && obj.code) {
console.log(‘obj.code’,obj.code)
}
}
参考资料

https://raoenhui.github.io/js/2018/12/16/tryCatch
ECMAScript 2015 -The try Statement
https://developers.google.com/web/updates/2015/05/automatically-pause-on-any-exception
https://v8docs.nodesource.com/node-0.8/d4/da0/v8_8h_source.html

Happy coding .. :)

正文完
 0

慎用try catch

68次阅读

共计 1174 个字符,预计需要花费 3 分钟才能阅读完成。

前言
ECMA-262 第 3 版引入了 try catch 语句,作为 JavaScript 中处理异常的一种标准方式。基本的语法如下所示。但是在前端 js 代码中很少看到 try catch 语句, 并不是所以代码都需要加 try catch 来作得不偿失的“保险”,下面来分析作为前端代码,哪些地方才需要真正加 try catch。
一、try catch 语法
try {
// 可能会导致错误的代码
} catch (error) {
// 在错误发生时怎么处理
}finally {
// 即使报错始终执行
}
二、try catch 缺点
1.try catch 耗性能
众所周知,js 以一个大括号 {} 决定一个块级作用域,代码进入 try catch 的时候 js 引擎会拷贝当前的词法环境,拷贝的其实就是当前 scope 下的所有的变量,这样消耗的性能是很大的,性能消耗与 try catch 代码量以及变量成正比。
2.try catch 捕获不到异步错误
尝试对异步方法进行 try catch 操作只能捕获当次事件循环内的异常,对 call back 执行时抛出的异常将无能为力。
try {
setTimeout(()=>{
const A = 1
A = 2
},0)
} catch (e) {
// 这里并不能捕获回调里面抛出的异常
console.log(“—–catch error——“)
console.log(e)
}
3.try catch 可能会导致报错点更模糊
try catch 语句中报错直接到 catch 中处理,而浏览器控制台看不到报错信息。但很多人并没有在 catch 中抛出报错信息,或改写成自己随意写的报错文言,这样其实不如直接看浏览器原生的报错修改 bug 更方便。
三、try catch 总结
说了这么多 try catch 的缺点,有些小伙伴们就会奇怪到里那里用 try catch 比较合适呢?
try catch 最适合处理那些我们无法控制的错误,如 I / O 操作,后端 java 读取 I / O 操作比较多比如读数据库,所以用 try catch 比较多。前端可以用在上传图片或 async await 同步调接口。
async function f() {
try {
await Promise.reject(‘ 出错了 ’);
} catch(e) {
}
return await Promise.resolve(‘hello world’);
}
但是大部分前端代码处理都不怎么依赖环境也没有 I / O 操作,都是自己写的代码,在明明白白地知道自己的代码会发生错误时,再使用 try catch 语句就不太合适了,所以慎用 try catch。
参考资料

https://raoenhui.github.io/js/2018/12/16/tryCatch/index.html
https://www.jb51.net/article/101291.htm
http://es6.ruanyifeng.com/#docs/async

Happy coding .. :)

正文完
 0