2009-02-17 66 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。在异常处理程序的情况下,将执行异常处理程序内的每行代码。那么,如果错误发生在第二行或第三行,会发生什么?然后,如果在执行任何条件之前检查条件,则代码中发生的事情与完全不同。

相关问题