慎用try catch

前言

自從ECMA-262第3版引入了try catch語句,做爲JavaScript中處理異常的一種標準方式。基本的語法以下所示。javascript

1、try catch基本語法

try {
    //可能會致使錯誤的代碼
} catch (error) {
    //在錯誤發生時怎麼處理
}finally {
     //即便報錯始終執行
 }

2、try catch特色

1.try catch耗性能
1.1 try catch耗性能原理

ECMAScript 2015 -The try Statementhtml

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: VarScopedDeclarationsjava

  • 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.513.15.6`。node

下面僅爲本妹子本身的翻譯理解,僅供參考git

上面大概說運行try catch時,須要將當前的詞法環境和做用域所有分別添加到catchFinally所要執行的代碼塊中。從上能夠推斷出try catch是消耗性能的。github

1.2 try catch耗性能實驗

webwxgetmsgimg.jpeg

下面我用Chrome62IE9分別添加多個try catch,進行對比實驗,雖然,很想拋棄萬惡的IE,可是不少國內的產品不答應呀,除非咱們去健身房再多練練,打一架,嘿嘿~~
1.2.1 實驗數據:web

//沒有加try catch
(function () {
  var i = 0;
     i++;
}())
//有try catch
(function () {
  var i = 0;
    try {
      i++;
    } catch (ex) {
    } finally {
    }
}())

1.2.2 實驗結果:
chrome62-simple.pngchrome

IE11-simple.png

chrome62-more.png

IE11-more.png

1.2.3 實驗連接:數據庫

https://jsperf.com/test-try-catch3

https://jsperf.com/test-try-catch

上面實驗數據對比得知,try catch會消耗性能,可是try catchChrome的影響比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.");

若是以爲自定義的報錯不合理,想看原生報錯,可使用ChromePause on exceptions功能
image.png

3、慎用try catch

try catch最適合處理那些咱們沒法控制的錯誤,如I/O操做等,後端nodeJsjava讀取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)
  }
}

參考資料

Happy coding .. :)

相關文章
相關標籤/搜索