2009-02-17 70 views
14

我很想談談這段代碼更高效的一些其他意見。基本上在下面的代碼中,有一個setInterval循環,並且在循環中運行代碼之前,我需要4個要求。所以在第1節中,我寫了一個if語句來檢查所有4.工作正常。Javascript:什麼是更有效率,IF塊或TRY/CATCH?

然後我切換到只使用try/catch,我想要執行的代碼坐在try {}中。邏輯是,在每個循環中,都會生成一個異常,但是會針對每個無效條件進行抑制。在所有條件都成立的最後一個循環中,代碼執行並清除間隔。

要麼工作。我喜歡try/catch方法,因爲我需要編寫更少的條件代碼,並擔心中斷。但我擔心try/catch效率非常低,特別是在100ms的setInterval()循環中。這裏對於其他聰明人心態有什麼看法?

的try/catch

var intvar = setInterval(function(){ 
try{  
    clearInterval(intvar); 

    jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>')); 

    //set display classes for nav 
    jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav 
    jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav 
}catch(err){} 
},100); 

IF塊

var intvar = setInterval(function(){ 

if(typeof jQuery == 'function' && typeof nav == 'object' && typeof pageid != 'undefined' && typeof document.getElementById('leftnav') == 'object'){ 
    clearInterval(intvar); 
    jQuery('#'+nav[pageid].t1+'>a').replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>')); 

    //set display classes for nav 
    jQuery('#'+nav[pageid].t1).addClass('selected').find('#'+nav[pageid].t2).addClass('subselect'); //topnav 
    jQuery('#'+nav[pageid].t3).addClass('selected').find('#'+nav[pageid].t4).addClass('subselect'); //leftnav 
} 

},100); 

回答

15

使用if語句。我不知道TRY/CATCH的開銷是多少,但我懷疑它遠不及評估一個布爾表達式。要打TRY/CATCH,你將不得不:執行一個語句,產生一個錯誤[與相關的開銷],記錄錯誤(大概),做一個堆棧跟蹤(大概),然後回到代碼中。此外,如果您必須在這些行附近調試代碼,那麼真正的錯誤可能會被您嘗試/捕獲的內容混淆。

此外,它是TRY/CATCH的濫用,可能會使您的代碼更難以閱讀。假設你這樣做了更長或更混淆的情況?你的漁獲最終會在哪裏?

這被稱爲Exception handling

編輯:正如下面的評論,你只需要運行時性能損失,如果你確實會導致異常。

16

異常應該用於特殊情況下(即你不要指望正常發生的事情,即)。通常情況下,您不應該使用異常來捕捉您可以使用if語句進行測試的內容。

另外,據我所知,例外情況比if語句要貴得多。

+5

完全與此相當大膽的這一說法。例如。在Python [`嘗試except`是首選(http://stackoverflow.com/questions/1835756/using-try-vs-if-in-python)另外,說什麼是「昂貴」的一些數據將是不錯。再次,在Python [「如果」更「昂貴」](http://stackoverflow.com/a/3929887/1167879)。 – 2013-02-23 18:11:28

+1

當然,OP在詢問Javascript而不是Python。另外,您可能想要閱讀您提供的鏈接。它說的基本上與cdmckay所做的一樣:使用異常來處理特殊情況。 – JAB 2015-11-12 17:48:56

+0

@AlexOkrushko的EAFP理念,更容易請求原諒比許可,由Python社區沒有JS採納。 – 2017-05-18 09:38:43

2

我會寫下面的代碼:

var startTime = (new Date()).getTime(); 
for (var i=0; i < 1000; ++i) intvar(); 
var endTime = (new Date()).getTime(); 
alert("Took " + ((endTime - startTime)/1000.0) " seconds"); 

然後我會嘗試intvar的兩個版本,看看哪個更快速地運行。我會自己做,但我沒有你做的頁面佈局,所以我的代碼不起作用。

一些文體評論 - 它似乎沒有必要測試jQuery是一個函數。如果不是,你的網頁很可能會搞砸,因此不運行intvar代碼不會對你有所幫助。如果你很少期望拋出異常,我會使用try/catch。

2

對於所提供的示例,您將try/catch包裝在應該始終運行的代碼塊周圍(除非發生某些可怕事情),使用try/catch是一種很好的形式。比喻你:你總是測試「天空是藍色的嗎?「在你的if語句中,或者你將它包裝在try/catch中,只有在天空正好變成綠色時纔會觸發它

如果處理用戶提供的輸入或者功能不存在要高得多,由於別的代碼發生。

請記住,如果你不引發異常你沒有任何平倉或跨代碼回溯。在這個例子中捕捉會只有在出現錯誤時才執行(jQuery缺失或某些此類事情),但if語句方法在每次單個調用時都會發生一次評估 - 您不應該做比您必須做的更多工作。

10

其他答案都是正確的,try/catch用於特殊情況和錯誤處理。 if條件適用於程序邏輯。 「哪個更快?」是錯誤的問題。

一個很好的經驗法則,如果你對異常什麼都不做,它可能不是一個例外!

要弄清楚要使用哪一個,讓我們分解一下if條件。

  1. typeof jQuery == 'function'是否定義了jQuery()函數?
  2. typeof nav == 'object' nav全局變量是否包含一個對象?
  3. typeof pageid != 'undefined'是否定義了pageid全局變量?
  4. typeof document.getElementById('leftnav') == 'object'該文件是否包含leftnav元素?

第一個顯然是個例外。如果沒有jQuery()函數,你沒有太多的工作。

第二個也是一個例外。如果沒有導航對象,你不會去任何地方。

第三是一個例外。你需要一個pageid來做任何事情。

第四種可能是邏輯。 「如果有一個leftnav元素,只運行這個代碼」。很難說,因爲其餘的代碼沒有引用leftnav元素!只有評論,紅旗。所以這可能是一個編程錯誤。

所以我可能做到這一點(與道歉,如果我屠宰的jQuery):

var intvar = setInterval(function() { 
    // If there's no leftnav element, don't do anything. 
    if(typeof document.getElementById('leftnav') != 'object') { 
     return; 
    } 

    try { 
     clearInterval(intvar); 
     jQuery('#'+nav[pageid].t1+'>a') 
      .replaceWith(jQuery('<span>'+jQuery('#'+nav[pageid].t1+'>a').text()+'</span>')); 

     //set display classes for nav 
     jQuery('#'+nav[pageid].t1) 
      .addClass('selected') 
      .find('#'+nav[pageid].t2) 
      .addClass('subselect');  //topnav 
     jQuery('#'+nav[pageid].t3) 
      .addClass('selected') 
      .find('#'+nav[pageid].t4) 
      .addClass('subselect');  //leftnav 
    } 
    catch(err) { 
     ...do something with the error... 
    } 
},100); 

...但我真的檢查,如果leftnav元素檢查是適用的。

最後,我不禁評論說這個「函數」與全局變量一起工作。您應該將navpageid傳遞到函數中,以保持封裝和您的理智。

0

要直接回答這個問題,與其他人一樣,如果實際存在錯誤,try..catch可能會更加昂貴。

要超出別人已經指出了代碼指出一些額外的錯誤:

這兩個代碼並不等同。爲了解釋,儘管代碼似乎做了完全相同的事情,但他們沒有。

在如果()檢查的情況下,執行該代碼的NONE。在異常處理程序的情況下,將執行異常處理程序內的每行代碼。那麼,如果錯誤發生在第二行或第三行,會發生什麼?然後,如果在執行任何條件之前檢查條件,則代碼中發生的事情與完全不同。

相關問題